| File: | root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/components/reputationservice/./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp |
| Warning: | line 1455, column 3 Value stored to 'rv' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
| 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| 4 | // See |
| 5 | // https://wiki.mozilla.org/Security/Features/Application_Reputation_Design_Doc |
| 6 | // for a description of Chrome's implementation of this feature. |
| 7 | #include "ApplicationReputation.h" |
| 8 | #include "chrome/common/safe_browsing/csd.pb.h" |
| 9 | |
| 10 | #include "nsIArray.h" |
| 11 | #include "nsIApplicationReputation.h" |
| 12 | #include "nsIChannel.h" |
| 13 | #include "nsIHttpChannel.h" |
| 14 | #include "nsIIOService.h" |
| 15 | #include "nsIObserverService.h" |
| 16 | #include "nsISimpleEnumerator.h" |
| 17 | #include "nsIStreamListener.h" |
| 18 | #include "nsIStringStream.h" |
| 19 | #include "nsITimer.h" |
| 20 | #include "nsIUploadChannel2.h" |
| 21 | #include "nsIURI.h" |
| 22 | #include "nsIURL.h" |
| 23 | #include "nsIUrlClassifierDBService.h" |
| 24 | #include "nsIURLFormatter.h" |
| 25 | #include "nsIX509Cert.h" |
| 26 | #include "nsIX509CertDB.h" |
| 27 | |
| 28 | #include "mozilla/BasePrincipal.h" |
| 29 | #include "mozilla/Components.h" |
| 30 | #include "mozilla/ErrorNames.h" |
| 31 | #include "mozilla/LoadContext.h" |
| 32 | #include "mozilla/Preferences.h" |
| 33 | #include "mozilla/ScopeExit.h" |
| 34 | #include "mozilla/Services.h" |
| 35 | #include "mozilla/glean/ReputationserviceMetrics.h" |
| 36 | #include "mozilla/TimeStamp.h" |
| 37 | #include "mozilla/intl/LocaleService.h" |
| 38 | |
| 39 | #include "nsCOMPtr.h" |
| 40 | #include "nsDebug.h" |
| 41 | #include "nsDependentSubstring.h" |
| 42 | #include "nsError.h" |
| 43 | #include "nsLocalFileCommon.h" |
| 44 | #include "nsNetCID.h" |
| 45 | #include "nsReadableUtils.h" |
| 46 | #include "nsServiceManagerUtils.h" |
| 47 | #include "nsString.h" |
| 48 | #include "nsTArray.h" |
| 49 | #include "nsThreadUtils.h" |
| 50 | |
| 51 | #include "nsIContentPolicy.h" |
| 52 | #include "nsICryptoHash.h" |
| 53 | #include "nsILoadInfo.h" |
| 54 | #include "nsContentUtils.h" |
| 55 | #include "nsWeakReference.h" |
| 56 | #include "nsIRedirectHistoryEntry.h" |
| 57 | |
| 58 | #include "ApplicationReputationTelemetryUtils.h" |
| 59 | |
| 60 | using mozilla::BasePrincipal; |
| 61 | using mozilla::OriginAttributes; |
| 62 | using mozilla::Preferences; |
| 63 | using mozilla::TimeStamp; |
| 64 | using mozilla::intl::LocaleService; |
| 65 | using safe_browsing::ClientDownloadRequest; |
| 66 | using safe_browsing::ClientDownloadRequest_CertificateChain; |
| 67 | using safe_browsing::ClientDownloadRequest_Resource; |
| 68 | using safe_browsing::ClientDownloadRequest_SignatureInfo; |
| 69 | |
| 70 | // Preferences that we need to initialize the query. |
| 71 | #define PREF_SB_APP_REP_URL"browser.safebrowsing.downloads.remote.url" "browser.safebrowsing.downloads.remote.url" |
| 72 | #define PREF_SB_MALWARE_ENABLED"browser.safebrowsing.malware.enabled" "browser.safebrowsing.malware.enabled" |
| 73 | #define PREF_SB_DOWNLOADS_ENABLED"browser.safebrowsing.downloads.enabled" "browser.safebrowsing.downloads.enabled" |
| 74 | #define PREF_SB_DOWNLOADS_REMOTE_ENABLED"browser.safebrowsing.downloads.remote.enabled" \ |
| 75 | "browser.safebrowsing.downloads.remote.enabled" |
| 76 | #define PREF_SB_DOWNLOADS_REMOTE_TIMEOUT"browser.safebrowsing.downloads.remote.timeout_ms" \ |
| 77 | "browser.safebrowsing.downloads.remote.timeout_ms" |
| 78 | #define PREF_DOWNLOAD_BLOCK_TABLE"urlclassifier.downloadBlockTable" "urlclassifier.downloadBlockTable" |
| 79 | #define PREF_DOWNLOAD_ALLOW_TABLE"urlclassifier.downloadAllowTable" "urlclassifier.downloadAllowTable" |
| 80 | |
| 81 | // Preferences that are needed to action the verdict. |
| 82 | #define PREF_BLOCK_DANGEROUS"browser.safebrowsing.downloads.remote.block_dangerous" \ |
| 83 | "browser.safebrowsing.downloads.remote.block_dangerous" |
| 84 | #define PREF_BLOCK_DANGEROUS_HOST"browser.safebrowsing.downloads.remote.block_dangerous_host" \ |
| 85 | "browser.safebrowsing.downloads.remote.block_dangerous_host" |
| 86 | #define PREF_BLOCK_POTENTIALLY_UNWANTED"browser.safebrowsing.downloads.remote.block_potentially_unwanted" \ |
| 87 | "browser.safebrowsing.downloads.remote.block_potentially_unwanted" |
| 88 | #define PREF_BLOCK_UNCOMMON"browser.safebrowsing.downloads.remote.block_uncommon" \ |
| 89 | "browser.safebrowsing.downloads.remote.block_uncommon" |
| 90 | |
| 91 | // MOZ_LOG=ApplicationReputation:5 |
| 92 | mozilla::LazyLogModule ApplicationReputationService::prlog( |
| 93 | "ApplicationReputation"); |
| 94 | #define LOG(args)do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, MOZ_LOG_EXPAND_ARGS args); } } while (0) \ |
| 95 | MOZ_LOG(ApplicationReputationService::prlog, mozilla::LogLevel::Debug, args)do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, MOZ_LOG_EXPAND_ARGS args); } } while (0) |
| 96 | #define LOG_ENABLED()(__builtin_expect(!!(mozilla::detail::log_test(ApplicationReputationService ::prlog, mozilla::LogLevel::Debug)), 0)) \ |
| 97 | MOZ_LOG_TEST(ApplicationReputationService::prlog, mozilla::LogLevel::Debug)(__builtin_expect(!!(mozilla::detail::log_test(ApplicationReputationService ::prlog, mozilla::LogLevel::Debug)), 0)) |
| 98 | |
| 99 | /** |
| 100 | * Our detection of executable/binary files uses 3 lists: |
| 101 | * - kNonBinaryExecutables (below) |
| 102 | * - kBinaryFileExtensions (below) |
| 103 | * - sExecutableExts (in nsLocalFileCommon) |
| 104 | * |
| 105 | * On Windows, the `sExecutableExts` list is used to determine whether files |
| 106 | * count as executable. For executable files, we will not offer an "open with" |
| 107 | * option when downloading, only "save as". |
| 108 | * |
| 109 | * On all platforms, the combination of these lists is used to determine |
| 110 | * whether files should be subject to application reputation checks. |
| 111 | * Specifically, all files with extensions that: |
| 112 | * - are in kBinaryFileExtensions, or |
| 113 | * - are in sExecutableExts **and not in kNonBinaryExecutables** |
| 114 | * |
| 115 | * will be subject to checks. |
| 116 | * |
| 117 | * There are tests that verify that these lists are sorted and that extensions |
| 118 | * never appear in both the sExecutableExts and kBinaryFileExtensions lists. |
| 119 | * |
| 120 | * When adding items to any lists: |
| 121 | * - please prefer adding to sExecutableExts unless it is imperative users can |
| 122 | * (potentially automatically!) open such files with a helper application |
| 123 | * without first saving them (and that outweighs any associated risk). |
| 124 | * - if adding executable items that shouldn't be submitted to apprep servers, |
| 125 | * add them to sExecutableExts and also to kNonBinaryExecutables. |
| 126 | * - always add an associated comment in the kBinaryFileExtensions list. Add |
| 127 | * a commented-out entry with an `exec` annotation if you add the actual |
| 128 | * entry in sExecutableExts. |
| 129 | * |
| 130 | * When removing items please consider whether items should still be in the |
| 131 | * sExecutableExts list even if removing them from the kBinaryFileExtensions |
| 132 | * list, and vice versa. |
| 133 | * |
| 134 | * Note that there is a GTest that does its best to check some of these |
| 135 | * invariants that you'll likely need to update if you're modifying these |
| 136 | * lists. |
| 137 | */ |
| 138 | |
| 139 | // Items that are in sExecutableExts but shouldn't be submitted for application |
| 140 | // reputation checks. |
| 141 | /* static */ |
| 142 | const char* const ApplicationReputationService::kNonBinaryExecutables[] = { |
| 143 | // clang-format off |
| 144 | ".ad", |
| 145 | ".afploc", |
| 146 | ".air", |
| 147 | ".atloc", |
| 148 | ".ftploc", |
| 149 | ".terminal", |
| 150 | // clang-format on |
| 151 | }; |
| 152 | |
| 153 | // Items that should be submitted for application reputation checks that users |
| 154 | // are able to open immediately (without first saving and then finding the |
| 155 | // file). If users shouldn't be able to open them immediately, add to |
| 156 | // sExecutableExts instead (see also the docstring comment above!). |
| 157 | /* static */ |
| 158 | const char* const ApplicationReputationService::kBinaryFileExtensions[] = { |
| 159 | // Originally extracted from the "File Type Policies" Chrome extension |
| 160 | // Items listed with an `exec` comment are in the sExecutableExts list in |
| 161 | // nsLocalFileCommon.h . |
| 162 | //".001", |
| 163 | //".7z", |
| 164 | //".ace", |
| 165 | //".accda", exec // MS Access database |
| 166 | //".accdb", exec // MS Access database |
| 167 | //".accde", exec // MS Access database |
| 168 | //".accdr", exec // MS Access database |
| 169 | ".action", // Mac script |
| 170 | //".ad", exec // Windows |
| 171 | //".ade", exec // MS Access |
| 172 | //".adp", exec // MS Access |
| 173 | //".air", exec // Adobe AIR installer; excluded from apprep checks. |
| 174 | ".apk", // Android package |
| 175 | //".app", exec // Executable application |
| 176 | ".applescript", |
| 177 | //".application", exec // MS ClickOnce |
| 178 | //".appref-ms", exec // MS ClickOnce |
| 179 | //".appx", exec |
| 180 | //".appxbundle", exec |
| 181 | //".arc", |
| 182 | //".arj", |
| 183 | ".as", // Mac archive |
| 184 | //".asp", exec // Windows Server script |
| 185 | ".asx", // Windows Media Player |
| 186 | //".b64", |
| 187 | //".balz", |
| 188 | //".bas", exec // Basic script |
| 189 | ".bash", // Linux shell |
| 190 | //".bat", exec // Windows shell |
| 191 | //".bhx", |
| 192 | ".bin", |
| 193 | ".btapp", // uTorrent and Transmission |
| 194 | ".btinstall", // uTorrent and Transmission |
| 195 | ".btkey", // uTorrent and Transmission |
| 196 | ".btsearch", // uTorrent and Transmission |
| 197 | ".btskin", // uTorrent and Transmission |
| 198 | ".bz", // Linux archive (bzip) |
| 199 | ".bz2", // Linux archive (bzip2) |
| 200 | ".bzip2", // Linux archive (bzip2) |
| 201 | ".cab", // Windows archive |
| 202 | ".caction", // Automator action |
| 203 | ".cdr", // Mac disk image |
| 204 | //".cer", exec // Signed certificate file |
| 205 | ".cfg", // Windows |
| 206 | ".chi", // Windows Help |
| 207 | //".chm", exec // Windows Help |
| 208 | ".class", // Java |
| 209 | //".cmd", exec // Windows executable |
| 210 | //".com", exec // Windows executable |
| 211 | //".command", exec // Mac script |
| 212 | ".configprofile", // Configuration file for Apple systems |
| 213 | ".cpgz", // Mac archive |
| 214 | ".cpi", // Control Panel Item. Executable used for adding icons |
| 215 | // to Control Panel |
| 216 | //".cpio", |
| 217 | //".cpl", exec // Windows executable |
| 218 | //".crt", exec // Windows signed certificate |
| 219 | ".crx", // Chrome extensions |
| 220 | ".csh", // Linux shell |
| 221 | //".csv", |
| 222 | ".dart", // Mac disk image |
| 223 | ".dc42", // Apple DiskCopy Image |
| 224 | ".deb", // Linux package |
| 225 | ".definition", // Automator action |
| 226 | ".desktop", // A shortcut that runs other files |
| 227 | //".der", exec // Signed certificate |
| 228 | ".dex", // Android |
| 229 | ".dht", // HTML |
| 230 | ".dhtm", // HTML |
| 231 | ".dhtml", // HTML |
| 232 | //".diagcab", exec // Executable windows archive, like .cab |
| 233 | ".diskcopy42", // Apple DiskCopy Image |
| 234 | ".dll", // Windows executable |
| 235 | ".dmg", // Mac disk image |
| 236 | ".dmgpart", // Mac disk image |
| 237 | ".doc", // MS Office |
| 238 | ".docb", // MS Office |
| 239 | ".docm", // MS Word |
| 240 | ".docx", // MS Word |
| 241 | ".dot", // MS Word |
| 242 | ".dotm", // MS Word |
| 243 | ".dott", // MS Office |
| 244 | ".dotx", // MS Word |
| 245 | ".drv", // Windows driver |
| 246 | ".dvdr", // Mac Disk image |
| 247 | ".dylib", // Mach object dynamic library file |
| 248 | ".efi", // Firmware |
| 249 | ".eml", // MS Outlook |
| 250 | //".exe", exec // Windows executable |
| 251 | //".fat", |
| 252 | //".fileloc", exec // Apple finder internet location data file |
| 253 | ".fon", // Windows font |
| 254 | //".fxp", exec // MS FoxPro |
| 255 | ".gadget", // Windows |
| 256 | //".gif", |
| 257 | ".grp", // Windows |
| 258 | ".gz", // Linux archive (gzip) |
| 259 | ".gzip", // Linux archive (gzip) |
| 260 | ".hfs", // Mac disk image |
| 261 | //".hlp", exec // Windows Help |
| 262 | ".hqx", // Mac archive |
| 263 | //".hta", exec // HTML trusted application |
| 264 | ".htm", |
| 265 | ".html", |
| 266 | ".htt", // MS HTML template |
| 267 | //".ica", |
| 268 | ".img", // Mac disk image |
| 269 | ".imgpart", // Mac disk image |
| 270 | //".inf", exec // Windows installer |
| 271 | //".inetloc", exec // Apple finder internet location data file |
| 272 | ".ini", // Generic config file |
| 273 | //".ins", exec // IIS config |
| 274 | ".internetconnect", // Configuration file for Apple system |
| 275 | //".inx", // InstallShield |
| 276 | ".iso", // CD image |
| 277 | //".isp", exec // IIS config |
| 278 | //".isu", // InstallShield |
| 279 | //".jar", exec // Java |
| 280 | #ifndef MOZ_ESR |
| 281 | //".jnlp", exec // Java |
| 282 | #endif |
| 283 | //".job", // Windows |
| 284 | //".jpg", |
| 285 | //".jpeg", |
| 286 | //".js", exec // JavaScript script |
| 287 | //".jse", exec // JScript |
| 288 | ".ksh", // Linux shell |
| 289 | //".lha", |
| 290 | //".library-ms", exec // Windows |
| 291 | //".lnk", exec // Windows |
| 292 | ".local", // Windows |
| 293 | //".lpaq1", |
| 294 | //".lpaq5", |
| 295 | //".lpaq8", |
| 296 | //".lzh", |
| 297 | //".lzma", |
| 298 | //".mad", exec // MS Access |
| 299 | //".maf", exec // MS Access |
| 300 | //".mag", exec // MS Access |
| 301 | //".mam", exec // MS Access |
| 302 | ".manifest", // Windows |
| 303 | //".maq", exec // MS Access |
| 304 | //".mar", exec // MS Access |
| 305 | //".mas", exec // MS Access |
| 306 | //".mat", exec // MS Access |
| 307 | //".mau", exec // Media attachment |
| 308 | //".mav", exec // MS Access |
| 309 | //".maw", exec // MS Access |
| 310 | //".mda", exec // MS Access |
| 311 | //".mdb", exec // MS Access |
| 312 | //".mde", exec // MS Access |
| 313 | //".mdt", exec // MS Access |
| 314 | //".mdw", exec // MS Access |
| 315 | //".mdz", exec // MS Access |
| 316 | ".mht", // MS HTML |
| 317 | ".mhtml", // MS HTML |
| 318 | ".mim", // MS Mail |
| 319 | //".mkv", |
| 320 | ".mmc", // MS Office |
| 321 | ".mobileconfig", // Configuration file for Apple systems |
| 322 | ".mof", // Windows |
| 323 | //".mov", |
| 324 | //".mp3", |
| 325 | //".mp4", |
| 326 | ".mpkg", // Mac installer |
| 327 | //".msc", exec // Windows executable |
| 328 | ".msg", // MS Outlook |
| 329 | //".msh", exec // Windows shell |
| 330 | //".msh1", exec // Windows shell |
| 331 | //".msh1xml", exec // Windows shell |
| 332 | //".msh2", exec // Windows shell |
| 333 | //".msh2xml", exec // Windows shell |
| 334 | //".mshxml", exec // Windows |
| 335 | //".msi", exec // Windows installer |
| 336 | //".msix", exec // Windows installer |
| 337 | //".msixbundle", exec // Windows installer |
| 338 | //".msp", exec // Windows installer |
| 339 | //".mst", exec // Windows installer |
| 340 | ".ndif", // Mac disk image |
| 341 | ".networkconnect", // Configuration file for Apple systems |
| 342 | //".ntfs", // 7z |
| 343 | ".ocx", // ActiveX |
| 344 | //".ops", exec // MS Office |
| 345 | ".osas", // AppleScript |
| 346 | ".osax", // AppleScript |
| 347 | //".out", // Linux binary |
| 348 | ".oxt", // OpenOffice extension, can execute arbitrary code |
| 349 | //".package", |
| 350 | //".paf", // PortableApps package |
| 351 | //".paq8f", |
| 352 | //".paq8jd", |
| 353 | //".paq8l", |
| 354 | //".paq8o", |
| 355 | ".partial", // Downloads |
| 356 | ".pax", // Mac archive |
| 357 | //".pcd", exec // Microsoft Visual Test |
| 358 | ".pdf", // Adobe Acrobat |
| 359 | //".pea", |
| 360 | ".pet", // Linux package |
| 361 | //".pif", exec // Windows |
| 362 | ".pkg", // Mac installer |
| 363 | ".pl", // Perl script |
| 364 | //".plg", exec // MS Visual Studio |
| 365 | //".png", |
| 366 | ".pot", // MS PowerPoint |
| 367 | ".potm", // MS PowerPoint |
| 368 | ".potx", // MS PowerPoint |
| 369 | ".ppam", // MS PowerPoint |
| 370 | ".pps", // MS PowerPoint |
| 371 | ".ppsm", // MS PowerPoint |
| 372 | ".ppsx", // MS PowerPoint |
| 373 | ".ppt", // MS PowerPoint |
| 374 | ".pptm", // MS PowerPoint |
| 375 | ".pptx", // MS PowerPoint |
| 376 | //".prf", exec // MS Outlook |
| 377 | //".prg", exec // Windows |
| 378 | ".ps1", // Windows shell |
| 379 | ".ps1xml", // Windows shell |
| 380 | ".ps2", // Windows shell |
| 381 | ".ps2xml", // Windows shell |
| 382 | ".psc1", // Windows shell |
| 383 | ".psc2", // Windows shell |
| 384 | //".pst", exec // MS Outlook |
| 385 | ".pup", // Linux package |
| 386 | ".py", // Python script |
| 387 | ".pyc", // Python binary |
| 388 | ".pyd", // Equivalent of a DLL, for python libraries |
| 389 | ".pyo", // Compiled python code |
| 390 | ".pyw", // Python GUI |
| 391 | //".quad", |
| 392 | //".r00", |
| 393 | //".r01", |
| 394 | //".r02", |
| 395 | //".r03", |
| 396 | //".r04", |
| 397 | //".r05", |
| 398 | //".r06", |
| 399 | //".r07", |
| 400 | //".r08", |
| 401 | //".r09", |
| 402 | //".r10", |
| 403 | //".r11", |
| 404 | //".r12", |
| 405 | //".r13", |
| 406 | //".r14", |
| 407 | //".r15", |
| 408 | //".r16", |
| 409 | //".r17", |
| 410 | //".r18", |
| 411 | //".r19", |
| 412 | //".r20", |
| 413 | //".r21", |
| 414 | //".r22", |
| 415 | //".r23", |
| 416 | //".r24", |
| 417 | //".r25", |
| 418 | //".r26", |
| 419 | //".r27", |
| 420 | //".r28", |
| 421 | //".r29", |
| 422 | //".rar", |
| 423 | ".rb", // Ruby script |
| 424 | //".reg", exec // Windows Registry |
| 425 | ".rels", // MS Office |
| 426 | //".rgs", // Windows Registry |
| 427 | ".rpm", // Linux package |
| 428 | ".rtf", // MS Office |
| 429 | //".run", // Linux shell |
| 430 | //".scf", exec // Windows shell |
| 431 | ".scpt", // AppleScript |
| 432 | ".scptd", // AppleScript |
| 433 | //".scr", exec // Windows |
| 434 | //".sct", exec // Windows shell |
| 435 | //".search-ms", exec // Windows Saved Search |
| 436 | ".seplugin", // AppleScript |
| 437 | ".service", // Systemd service unit file |
| 438 | //".settingcontent-ms", exec // Windows settings |
| 439 | ".sh", // Linux shell |
| 440 | ".shar", // Linux shell |
| 441 | //".shb", exec // Windows |
| 442 | //".shs", exec // Windows shell |
| 443 | ".sht", // HTML |
| 444 | ".shtm", // HTML |
| 445 | ".shtml", // HTML |
| 446 | ".sldm", // MS PowerPoint |
| 447 | ".sldx", // MS PowerPoint |
| 448 | ".slk", // MS Excel |
| 449 | ".slp", // Linux package |
| 450 | ".smi", // Mac disk image |
| 451 | ".sparsebundle", // Mac disk image |
| 452 | ".sparseimage", // Mac disk image |
| 453 | ".spl", // Adobe Flash |
| 454 | //".squashfs", |
| 455 | ".svg", |
| 456 | ".swf", // Adobe Flash |
| 457 | ".swm", // Windows Imaging |
| 458 | ".sys", // Windows |
| 459 | ".tar", // Linux archive |
| 460 | ".taz", // Linux archive (bzip2) |
| 461 | ".tbz", // Linux archive (bzip2) |
| 462 | ".tbz2", // Linux archive (bzip2) |
| 463 | ".tcsh", // Linux shell |
| 464 | //".tif", |
| 465 | ".tgz", // Linux archive (gzip) |
| 466 | //".toast", // Roxio disk image |
| 467 | ".torrent", // Bittorrent |
| 468 | ".tpz", // Linux archive (gzip) |
| 469 | //".txt", |
| 470 | ".txz", // Linux archive (xz) |
| 471 | ".tz", // Linux archive (gzip) |
| 472 | //".u3p", // U3 Smart Apps |
| 473 | ".udf", // MS Excel |
| 474 | ".udif", // Mac disk image |
| 475 | //".url", exec // Windows |
| 476 | //".uu", |
| 477 | //".uue", |
| 478 | //".vb", exec // Visual Basic script |
| 479 | //".vbe", exec // Visual Basic script |
| 480 | //".vbs", exec // Visual Basic script |
| 481 | //".vbscript", // Visual Basic script |
| 482 | //".vdx", exec // MS Visio |
| 483 | ".vhd", // Windows virtual hard drive |
| 484 | ".vhdx", // Windows virtual hard drive |
| 485 | ".vmdk", // VMware virtual disk |
| 486 | //".vsd", exec // MS Visio |
| 487 | //".vsdm", exec // MS Visio |
| 488 | //".vsdx", exec // MS Visio |
| 489 | //".vsmacros", exec // MS Visual Studio |
| 490 | //".vss", exec // MS Visio |
| 491 | //".vssm", exec // MS Visio |
| 492 | //".vssx", exec // MS Visio |
| 493 | //".vst", exec // MS Visio |
| 494 | //".vstm", exec // MS Visio |
| 495 | //".vstx", exec // MS Visio |
| 496 | //".vsw", exec // MS Visio |
| 497 | //".vsx", exec // MS Visio |
| 498 | //".vtx", exec // MS Visio |
| 499 | //".wav", |
| 500 | //".webloc", // MacOS website location file |
| 501 | //".webp", |
| 502 | ".website", // Windows |
| 503 | ".wflow", // Automator action |
| 504 | ".wim", // Windows Imaging |
| 505 | ".workflow", // Mac Automator |
| 506 | //".wrc", // FreeArc archive |
| 507 | //".ws", exec // Windows script |
| 508 | ".wsb", // Windows Sandbox configuration |
| 509 | //".wsc", exec // Windows script |
| 510 | //".wsf", exec // Windows script |
| 511 | //".wsh", exec // Windows script |
| 512 | ".xar", // MS Excel |
| 513 | ".xbap", // XAML Browser Application |
| 514 | ".xht", |
| 515 | ".xhtm", |
| 516 | ".xhtml", |
| 517 | ".xip", // Mac archive |
| 518 | ".xla", // MS Excel |
| 519 | ".xlam", // MS Excel |
| 520 | ".xldm", // MS Excel |
| 521 | //".xll", exec // MS Excel |
| 522 | ".xlm", // MS Excel |
| 523 | ".xls", // MS Excel |
| 524 | ".xlsb", // MS Excel |
| 525 | ".xlsm", // MS Excel |
| 526 | ".xlsx", // MS Excel |
| 527 | ".xlt", // MS Excel |
| 528 | ".xltm", // MS Excel |
| 529 | ".xltx", // MS Excel |
| 530 | ".xlw", // MS Excel |
| 531 | ".xml", // MS Excel |
| 532 | ".xnk", // MS Exchange |
| 533 | //".xrm-ms", exec // Windows |
| 534 | ".xsd", // XML schema definition |
| 535 | ".xsl", // XML Stylesheet |
| 536 | //".xxe", |
| 537 | ".xz", // Linux archive (xz) |
| 538 | ".z", // InstallShield |
| 539 | #ifdef XP_WIN // disable on Mac/Linux, see 1167493 |
| 540 | ".zip", // Generic archive |
| 541 | #endif |
| 542 | ".zipx", // WinZip |
| 543 | //".zpaq", |
| 544 | }; |
| 545 | |
| 546 | static const char* const kMozNonBinaryExecutables[] = { |
| 547 | ".001", ".7z", ".ace", ".arc", ".arj", ".b64", ".balz", |
| 548 | ".bhx", ".cpio", ".fat", ".lha", ".lpaq1", ".lpaq5", ".lpaq8", |
| 549 | ".lzh", ".lzma", ".ntfs", ".paq8f", ".paq8jd", ".paq8l", ".paq8o", |
| 550 | ".pea", ".quad", ".r00", ".r01", ".r02", ".r03", ".r04", |
| 551 | ".r05", ".r06", ".r07", ".r08", ".r09", ".r10", ".r11", |
| 552 | ".r12", ".r13", ".r14", ".r15", ".r16", ".r17", ".r18", |
| 553 | ".r19", ".r20", ".r21", ".r22", ".r23", ".r24", ".r25", |
| 554 | ".r26", ".r27", ".r28", ".r29", ".rar", ".squashfs", ".uu", |
| 555 | ".uue", ".wrc", ".xxe", ".zpaq", ".toast", |
| 556 | }; |
| 557 | |
| 558 | static const char* const kSafeFileExtensions[] = { |
| 559 | ".jpg", ".jpeg", ".mp3", ".mp4", ".png", ".csv", ".ica", |
| 560 | ".gif", ".txt", ".package", ".tif", ".webp", ".mkv", ".wav", |
| 561 | ".mov", ".paf", ".vbscript", ".ad", ".inx", ".isu", ".job", |
| 562 | ".rgs", ".u3p", ".out", ".run", ".bmp", ".css", ".ehtml", |
| 563 | ".flac", ".ico", ".jfif", ".m4a", ".m4v", ".mpeg", ".mpg", |
| 564 | ".oga", ".ogg", ".ogm", ".ogv", ".opus", ".pjp", ".pjpeg", |
| 565 | ".svgz", ".text", ".tiff", ".weba", ".webm", ".xbm", |
| 566 | }; |
| 567 | |
| 568 | enum class LookupType { AllowlistOnly, BlocklistOnly, BothLists }; |
| 569 | |
| 570 | // Define the reasons that download protection service accepts or blocks this |
| 571 | // download. This is now used for telemetry purposes and xpcshell test. Please |
| 572 | // also update the xpcshell-test if a reason is added. |
| 573 | // |
| 574 | // LocalWhitelist : URL is found in the local whitelist |
| 575 | // LocalBlocklist : URL is found in the local blocklist |
| 576 | // NonBinary : The downloaded non-binary file is not found in the |
| 577 | // local blocklist VerdictSafe : Remote lookup reports the download is |
| 578 | // safe VerdictUnknown : Remote lookup reports unknown, we treat this as a |
| 579 | // safe download VerdictDangerous : Remote lookup reports the download is |
| 580 | // dangerous VerdictDangerousHost : Remote lookup reports the download is from a |
| 581 | // dangerous host VerdictUnwanted : Remote lookup reports the download is |
| 582 | // potentially unwatned VerdictUncommon : Remote lookup reports the |
| 583 | // download is uncommon VerdictUnrecognized : The verdict type from remote |
| 584 | // lookup is not defined in the csd.proto DangerousPrefOff : The download is |
| 585 | // dangerous, but the corresponding preference is off DangerousHostPrefOff : The |
| 586 | // download is from a dangerous host, but the corresponding preference is off |
| 587 | // UnwantedPrefOff : The download is potentially unwanted, but the |
| 588 | // corresponding preference is off UncommonPrefOff : The download us |
| 589 | // uncommon, but the coressponding preference is off NetworkError : |
| 590 | // There is an error while requesting remote lookup RemoteLookupDisabled : |
| 591 | // Remote lookup is disabled or the remote lookup URL is empty InternalError : |
| 592 | // An unexpected internal error DPDisabled : Download protection is |
| 593 | // disabled |
| 594 | using Reason = mozilla::glean::application_reputation::ReasonLabel; |
| 595 | |
| 596 | class PendingDBLookup; |
| 597 | |
| 598 | // A single use class private to ApplicationReputationService encapsulating an |
| 599 | // nsIApplicationReputationQuery and an nsIApplicationReputationCallback. Once |
| 600 | // created by ApplicationReputationService, it is guaranteed to call mCallback. |
| 601 | // This class is private to ApplicationReputationService. |
| 602 | class PendingLookup final : public nsIStreamListener, |
| 603 | public nsITimerCallback, |
| 604 | public nsINamed, |
| 605 | public nsIObserver, |
| 606 | public nsSupportsWeakReference { |
| 607 | public: |
| 608 | NS_DECL_ISUPPORTSpublic: virtual nsresult QueryInterface(const nsIID& aIID , void** aInstancePtr) override; virtual MozExternalRefCountType AddRef(void) override; virtual MozExternalRefCountType Release (void) override; using HasThreadSafeRefCnt = std::false_type; protected: nsAutoRefCnt mRefCnt; nsAutoOwningThread _mOwningThread ; public: |
| 609 | NS_DECL_NSIREQUESTOBSERVERvirtual nsresult OnStartRequest(nsIRequest *aRequest) override ; virtual nsresult OnStopRequest(nsIRequest *aRequest, nsresult aStatusCode) override; |
| 610 | NS_DECL_NSISTREAMLISTENERvirtual nsresult OnDataAvailable(nsIRequest *aRequest, nsIInputStream *aInputStream, uint64_t aOffset, uint32_t aCount) override; |
| 611 | NS_DECL_NSITIMERCALLBACKvirtual nsresult Notify(nsITimer *timer) override; inline void _ensure_GetName_exists(void) { static_assert(std::is_convertible_v <decltype(this), nsINamed*>, "nsITimerCallback implementations must also implement nsINamed" ); } |
| 612 | NS_DECL_NSINAMEDvirtual nsresult GetName(nsACString& aName) override; |
| 613 | NS_DECL_NSIOBSERVERvirtual nsresult Observe(nsISupports *aSubject, const char * aTopic , const char16_t * aData) override; |
| 614 | |
| 615 | // Constructor and destructor. |
| 616 | PendingLookup(nsIApplicationReputationQuery* aQuery, |
| 617 | nsIApplicationReputationCallback* aCallback); |
| 618 | |
| 619 | // Start the lookup. The lookup may have 2 parts: local and remote. In the |
| 620 | // local lookup, PendingDBLookups are created to query the local allow and |
| 621 | // blocklists for various URIs associated with this downloaded file. In the |
| 622 | // event that no results are found, a remote lookup is sent to the Application |
| 623 | // Reputation server. |
| 624 | nsresult StartLookup(); |
| 625 | |
| 626 | private: |
| 627 | ~PendingLookup(); |
| 628 | |
| 629 | friend class PendingDBLookup; |
| 630 | |
| 631 | // Telemetry states. |
| 632 | // Status of the remote response (valid or not). |
| 633 | enum SERVER_RESPONSE_TYPES { |
| 634 | SERVER_RESPONSE_VALID = 0, |
| 635 | SERVER_RESPONSE_FAILED = 1, |
| 636 | SERVER_RESPONSE_INVALID = 2, |
| 637 | }; |
| 638 | |
| 639 | // The target filename for the downloaded file. |
| 640 | nsCString mFileName; |
| 641 | |
| 642 | // True if extension of this file matches any extension in the |
| 643 | // kBinaryFileExtensions or sExecutableExts list. |
| 644 | bool mIsBinaryFile; |
| 645 | |
| 646 | // Number of blocklist and allowlist hits we have seen. |
| 647 | uint32_t mBlocklistCount; |
| 648 | uint32_t mAllowlistCount; |
| 649 | |
| 650 | // The query containing metadata about the downloaded file. |
| 651 | nsCOMPtr<nsIApplicationReputationQuery> mQuery; |
| 652 | |
| 653 | // The callback with which to report the verdict. |
| 654 | nsCOMPtr<nsIApplicationReputationCallback> mCallback; |
| 655 | |
| 656 | // An array of strings created from certificate information used to whitelist |
| 657 | // the downloaded file. |
| 658 | nsTArray<nsCString> mAllowlistSpecs; |
| 659 | // The source URI of the download (i.e. final URI after any redirects). |
| 660 | nsTArray<nsCString> mAnylistSpecs; |
| 661 | // The referrer and possibly any redirects. |
| 662 | nsTArray<nsCString> mBlocklistSpecs; |
| 663 | |
| 664 | // When we started this query |
| 665 | TimeStamp mStartTime; |
| 666 | |
| 667 | // The channel used to talk to the remote lookup server |
| 668 | nsCOMPtr<nsIChannel> mChannel; |
| 669 | |
| 670 | // Timer to abort this lookup if it takes too long |
| 671 | nsCOMPtr<nsITimer> mTimeoutTimer; |
| 672 | |
| 673 | // A protocol buffer for storing things we need in the remote request. We |
| 674 | // store the resource chain (redirect information) as well as signature |
| 675 | // information extracted using the Windows Authenticode API, if the binary is |
| 676 | // signed. |
| 677 | ClientDownloadRequest mRequest; |
| 678 | |
| 679 | // The response from the application reputation query. This is read in chunks |
| 680 | // as part of our nsIStreamListener implementation and may contain embedded |
| 681 | // NULLs. |
| 682 | nsCString mResponse; |
| 683 | |
| 684 | // The clock records the start time of a remote lookup request, used by |
| 685 | // telemetry. |
| 686 | PRIntervalTime mTelemetryRemoteRequestStartMs; |
| 687 | |
| 688 | // Returns the type of download binary for the file. |
| 689 | ClientDownloadRequest::DownloadType GetDownloadType( |
| 690 | const nsACString& aFilename); |
| 691 | |
| 692 | // Clean up and call the callback. PendingLookup must not be used after this |
| 693 | // function is called. |
| 694 | nsresult OnComplete(uint32_t aVerdict, Reason aReason, nsresult aRv); |
| 695 | |
| 696 | // Wrapper function for nsIStreamListener.onStopRequest to make it easy to |
| 697 | // guarantee calling the callback |
| 698 | nsresult OnStopRequestInternal(nsIRequest* aRequest, nsresult aResult, |
| 699 | uint32_t& aVerdict, Reason& aReason); |
| 700 | |
| 701 | // Return the hex-encoded hash of the whole URI. |
| 702 | nsresult GetSpecHash(nsACString& aSpec, nsACString& hexEncodedHash); |
| 703 | |
| 704 | // Strip url parameters, fragments, and user@pass fields from the URI spec |
| 705 | // using nsIURL. Hash data URIs and return blob URIs unfiltered. |
| 706 | nsresult GetStrippedSpec(nsIURI* aUri, nsACString& spec); |
| 707 | |
| 708 | // Escape '/' and '%' in certificate attribute values. |
| 709 | nsCString EscapeCertificateAttribute(const nsACString& aAttribute); |
| 710 | |
| 711 | // Escape ':' in fingerprint values. |
| 712 | nsCString EscapeFingerprint(const nsACString& aAttribute); |
| 713 | |
| 714 | // Generate whitelist strings for the given certificate pair from the same |
| 715 | // certificate chain. |
| 716 | nsresult GenerateWhitelistStringsForPair(nsIX509Cert* certificate, |
| 717 | nsIX509Cert* issuer); |
| 718 | |
| 719 | // Generate whitelist strings for the given certificate chain, which starts |
| 720 | // with the signer and may go all the way to the root cert. |
| 721 | nsresult GenerateWhitelistStringsForChain( |
| 722 | const ClientDownloadRequest_CertificateChain& aChain); |
| 723 | |
| 724 | // For signed binaries, generate strings of the form: |
| 725 | // http://sb-ssl.google.com/safebrowsing/csd/certificate/ |
| 726 | // <issuer_cert_sha1_fingerprint>[/CN=<cn>][/O=<org>][/OU=<unit>] |
| 727 | // for each (cert, issuer) pair in each chain of certificates that is |
| 728 | // associated with the binary. |
| 729 | nsresult GenerateWhitelistStrings(); |
| 730 | |
| 731 | // Parse the XPCOM certificate lists and stick them into the protocol buffer |
| 732 | // version. |
| 733 | nsresult ParseCertificates( |
| 734 | const nsTArray<nsTArray<nsTArray<uint8_t>>>& aSigArray); |
| 735 | |
| 736 | // Adds the redirects to mBlocklistSpecs to be looked up. |
| 737 | nsresult AddRedirects(nsIArray* aRedirects); |
| 738 | |
| 739 | // Helper function to ensure that we call PendingLookup::LookupNext or |
| 740 | // PendingLookup::OnComplete. |
| 741 | nsresult DoLookupInternal(); |
| 742 | |
| 743 | // Looks up all the URIs that may be responsible for allowlisting or |
| 744 | // blocklisting the downloaded file. These URIs may include whitelist strings |
| 745 | // generated by certificates verifying the binary as well as the target URI |
| 746 | // from which the file was downloaded. |
| 747 | nsresult LookupNext(); |
| 748 | |
| 749 | // Sends a query to the remote application reputation service. Returns NS_OK |
| 750 | // on success. |
| 751 | nsresult SendRemoteQuery(); |
| 752 | |
| 753 | // Helper function to ensure that we always call the callback. |
| 754 | nsresult SendRemoteQueryInternal(Reason& aReason); |
| 755 | }; |
| 756 | |
| 757 | // A single-use class for looking up a single URI in the safebrowsing DB. This |
| 758 | // class is private to PendingLookup. |
| 759 | class PendingDBLookup final : public nsIUrlClassifierCallback { |
| 760 | public: |
| 761 | NS_DECL_ISUPPORTSpublic: virtual nsresult QueryInterface(const nsIID& aIID , void** aInstancePtr) override; virtual MozExternalRefCountType AddRef(void) override; virtual MozExternalRefCountType Release (void) override; using HasThreadSafeRefCnt = std::false_type; protected: nsAutoRefCnt mRefCnt; nsAutoOwningThread _mOwningThread ; public: |
| 762 | NS_DECL_NSIURLCLASSIFIERCALLBACKvirtual nsresult HandleEvent(const nsACString& value) override ; |
| 763 | |
| 764 | // Constructor and destructor |
| 765 | explicit PendingDBLookup(PendingLookup* aPendingLookup); |
| 766 | |
| 767 | // Look up the given URI in the safebrowsing DBs, optionally on both the allow |
| 768 | // list and the blocklist. If there is a match, call |
| 769 | // PendingLookup::OnComplete. Otherwise, call PendingLookup::LookupNext. |
| 770 | nsresult LookupSpec(const nsACString& aSpec, const LookupType& aLookupType); |
| 771 | |
| 772 | private: |
| 773 | ~PendingDBLookup(); |
| 774 | |
| 775 | // The download appeared on the allowlist, blocklist, or no list (and thus |
| 776 | // could trigger a remote query. |
| 777 | enum LIST_TYPES { |
| 778 | ALLOW_LIST = 0, |
| 779 | BLOCK_LIST = 1, |
| 780 | NO_LIST = 2, |
| 781 | }; |
| 782 | |
| 783 | nsCString mSpec; |
| 784 | LookupType mLookupType; |
| 785 | RefPtr<PendingLookup> mPendingLookup; |
| 786 | nsresult LookupSpecInternal(const nsACString& aSpec); |
| 787 | }; |
| 788 | |
| 789 | NS_IMPL_ISUPPORTS(PendingDBLookup, nsIUrlClassifierCallback)MozExternalRefCountType PendingDBLookup::AddRef(void) { static_assert (!std::is_destructible_v<PendingDBLookup>, "Reference-counted class " "PendingDBLookup" " should not have a public destructor. " "Make this class's destructor non-public" ); do { static_assert( mozilla::detail::AssertionConditionType <decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0" " (" "illegal refcnt" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 789); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0" ") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 789 ); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); do { static_assert( mozilla::detail::AssertionConditionType <decltype("PendingDBLookup" != nullptr)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!("PendingDBLookup" != nullptr ))), 0))) { do { } while (false); MOZ_ReportAssertionFailure( "\"PendingDBLookup\" != nullptr" " (" "Must specify a name" ")" , "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 789); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingDBLookup\" != nullptr" ") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null , 789); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership ("PendingDBLookup" " not thread-safe"); nsrefcnt count = ++mRefCnt ; NS_LogAddRef((this), (count), ("PendingDBLookup"), (uint32_t )(sizeof(*this))); return count; } MozExternalRefCountType PendingDBLookup ::Release(void) { do { static_assert( mozilla::detail::AssertionConditionType <decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0 ))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0" " (" "dup release" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 789); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0" ") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 789 ); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); do { static_assert( mozilla::detail::AssertionConditionType <decltype("PendingDBLookup" != nullptr)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!("PendingDBLookup" != nullptr ))), 0))) { do { } while (false); MOZ_ReportAssertionFailure( "\"PendingDBLookup\" != nullptr" " (" "Must specify a name" ")" , "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 789); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingDBLookup\" != nullptr" ") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null , 789); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership ("PendingDBLookup" " not thread-safe"); const char* const nametmp = "PendingDBLookup"; nsrefcnt count = --mRefCnt; NS_LogRelease ((this), (count), (nametmp)); if (count == 0) { mRefCnt = 1; delete (this); return 0; } return count; } nsresult PendingDBLookup ::QueryInterface(const nsIID& aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION , "QueryInterface requires a non-NULL destination!", "aInstancePtr" , "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 789); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE ; static_assert(1 > 0, "Need more arguments to NS_INTERFACE_TABLE" ); static const QITableEntry table[] = { {&mozilla::detail ::kImplementedIID<PendingDBLookup, nsIUrlClassifierCallback >, int32_t( reinterpret_cast<char*>(static_cast<nsIUrlClassifierCallback *>((PendingDBLookup*)0x1000)) - reinterpret_cast<char*> ((PendingDBLookup*)0x1000))}, {&mozilla::detail::kImplementedIID <PendingDBLookup, nsISupports>, int32_t(reinterpret_cast <char*>(static_cast<nsISupports*>( static_cast< nsIUrlClassifierCallback*>((PendingDBLookup*)0x1000))) - reinterpret_cast <char*>((PendingDBLookup*)0x1000))}, { nullptr, 0 } } ; static_assert(std::size(table) > 1, "need at least 1 interface" ); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID , aInstancePtr, table); return rv; } |
| 790 | |
| 791 | PendingDBLookup::PendingDBLookup(PendingLookup* aPendingLookup) |
| 792 | : mLookupType(LookupType::BothLists), mPendingLookup(aPendingLookup) { |
| 793 | LOG(("Created pending DB lookup [this = %p]", this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Created pending DB lookup [this = %p]" , this); } } while (0); |
| 794 | } |
| 795 | |
| 796 | PendingDBLookup::~PendingDBLookup() { |
| 797 | LOG(("Destroying pending DB lookup [this = %p]", this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Destroying pending DB lookup [this = %p]" , this); } } while (0); |
| 798 | mPendingLookup = nullptr; |
| 799 | } |
| 800 | |
| 801 | nsresult PendingDBLookup::LookupSpec(const nsACString& aSpec, |
| 802 | const LookupType& aLookupType) { |
| 803 | LOG(("Checking principal %s [this=%p]", PromiseFlatCString(aSpec).get(),do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Checking principal %s [this=%p]" , TPromiseFlatString<char>(aSpec).get(), this); } } while (0) |
| 804 | this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Checking principal %s [this=%p]" , TPromiseFlatString<char>(aSpec).get(), this); } } while (0); |
| 805 | mSpec = aSpec; |
| 806 | mLookupType = aLookupType; |
| 807 | nsresult rv = LookupSpecInternal(aSpec); |
| 808 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
| 809 | nsAutoCString errorName; |
| 810 | mozilla::GetErrorName(rv, errorName); |
| 811 | LOG(("Error in LookupSpecInternal() [rv = %s, this = %p]", errorName.get(),do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Error in LookupSpecInternal() [rv = %s, this = %p]" , errorName.get(), this); } } while (0) |
| 812 | this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Error in LookupSpecInternal() [rv = %s, this = %p]" , errorName.get(), this); } } while (0); |
| 813 | return mPendingLookup->LookupNext(); // ignore this lookup and move to next |
| 814 | } |
| 815 | // LookupSpecInternal has called nsIUrlClassifierCallback.lookup, which is |
| 816 | // guaranteed to call HandleEvent. |
| 817 | return rv; |
| 818 | } |
| 819 | |
| 820 | nsresult PendingDBLookup::LookupSpecInternal(const nsACString& aSpec) { |
| 821 | nsresult rv; |
| 822 | |
| 823 | nsCOMPtr<nsIURI> uri; |
| 824 | nsCOMPtr<nsIIOService> ios = do_GetService(NS_IOSERVICE_CONTRACTID"@mozilla.org/network/io-service;1", &rv); |
| 825 | rv = ios->NewURI(aSpec, nullptr, nullptr, getter_AddRefs(uri)); |
| 826 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 826); return rv; } } while (false); |
| 827 | |
| 828 | OriginAttributes attrs; |
| 829 | nsCOMPtr<nsIPrincipal> principal = |
| 830 | BasePrincipal::CreateContentPrincipal(uri, attrs); |
| 831 | if (!principal) { |
| 832 | return NS_ERROR_FAILURE; |
| 833 | } |
| 834 | |
| 835 | // Check local lists to see if the URI has already been whitelisted or |
| 836 | // blacklisted. |
| 837 | LOG(("Checking DB service for principal %s [this = %p]", mSpec.get(), this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Checking DB service for principal %s [this = %p]" , mSpec.get(), this); } } while (0); |
| 838 | nsCOMPtr<nsIUrlClassifierDBService> dbService = |
| 839 | mozilla::components::UrlClassifierDB::Service(&rv); |
| 840 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 840); return rv; } } while (false); |
| 841 | |
| 842 | nsAutoCString tables; |
| 843 | nsAutoCString allowlist; |
| 844 | Preferences::GetCString(PREF_DOWNLOAD_ALLOW_TABLE"urlclassifier.downloadAllowTable", allowlist); |
| 845 | if ((mLookupType != LookupType::BlocklistOnly) && !allowlist.IsEmpty()) { |
| 846 | tables.Append(allowlist); |
| 847 | } |
| 848 | nsAutoCString blocklist; |
| 849 | Preferences::GetCString(PREF_DOWNLOAD_BLOCK_TABLE"urlclassifier.downloadBlockTable", blocklist); |
| 850 | if ((mLookupType != LookupType::AllowlistOnly) && !blocklist.IsEmpty()) { |
| 851 | if (!tables.IsEmpty()) { |
| 852 | tables.Append(','); |
| 853 | } |
| 854 | tables.Append(blocklist); |
| 855 | } |
| 856 | if (principal->IsSystemPrincipal()) { |
| 857 | return mPendingLookup->LookupNext(); |
| 858 | } |
| 859 | return dbService->Lookup(principal, tables, this); |
| 860 | } |
| 861 | |
| 862 | NS_IMETHODIMPnsresult |
| 863 | PendingDBLookup::HandleEvent(const nsACString& tables) { |
| 864 | // HandleEvent is guaranteed to call either: |
| 865 | // 1) PendingLookup::OnComplete if the URL matches the blocklist, or |
| 866 | // 2) PendingLookup::LookupNext if the URL does not match the blocklist. |
| 867 | // Blocklisting trumps allowlisting. |
| 868 | nsAutoCString blockList; |
| 869 | Preferences::GetCString(PREF_DOWNLOAD_BLOCK_TABLE"urlclassifier.downloadBlockTable", blockList); |
| 870 | if ((mLookupType != LookupType::AllowlistOnly) && !blockList.IsEmpty() && |
| 871 | FindInReadable(blockList, tables)) { |
| 872 | mPendingLookup->mBlocklistCount++; |
| 873 | mozilla::glean::application_reputation::local.AccumulateSingleSample( |
| 874 | BLOCK_LIST); |
| 875 | LOG(("Found principal %s on blocklist [this = %p]", mSpec.get(), this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Found principal %s on blocklist [this = %p]" , mSpec.get(), this); } } while (0); |
| 876 | return mPendingLookup->OnComplete( |
| 877 | nsIApplicationReputationService::VERDICT_DANGEROUS, |
| 878 | Reason::eLocalblocklist, NS_OK); |
| 879 | } |
| 880 | |
| 881 | nsAutoCString allowList; |
| 882 | Preferences::GetCString(PREF_DOWNLOAD_ALLOW_TABLE"urlclassifier.downloadAllowTable", allowList); |
| 883 | if ((mLookupType != LookupType::BlocklistOnly) && !allowList.IsEmpty() && |
| 884 | FindInReadable(allowList, tables)) { |
| 885 | mPendingLookup->mAllowlistCount++; |
| 886 | mozilla::glean::application_reputation::local.AccumulateSingleSample( |
| 887 | ALLOW_LIST); |
| 888 | LOG(("Found principal %s on allowlist [this = %p]", mSpec.get(), this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Found principal %s on allowlist [this = %p]" , mSpec.get(), this); } } while (0); |
| 889 | // Don't call onComplete, since blocklisting trumps allowlisting |
| 890 | return mPendingLookup->LookupNext(); |
| 891 | } |
| 892 | |
| 893 | LOG(("Didn't find principal %s on any list [this = %p]", mSpec.get(), this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Didn't find principal %s on any list [this = %p]" , mSpec.get(), this); } } while (0); |
| 894 | mozilla::glean::application_reputation::local.AccumulateSingleSample(NO_LIST); |
| 895 | return mPendingLookup->LookupNext(); |
| 896 | } |
| 897 | |
| 898 | NS_IMPL_ISUPPORTS(PendingLookup, nsIStreamListener, nsIRequestObserver,MozExternalRefCountType PendingLookup::AddRef(void) { static_assert (!std::is_destructible_v<PendingLookup>, "Reference-counted class " "PendingLookup" " should not have a public destructor. " "Make this class's destructor non-public" ); do { static_assert( mozilla::detail::AssertionConditionType <decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0" " (" "illegal refcnt" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0" ") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 900 ); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); do { static_assert( mozilla::detail::AssertionConditionType <decltype("PendingLookup" != nullptr)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!("PendingLookup" != nullptr)) ), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"PendingLookup\" != nullptr" " (" "Must specify a name" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr" ") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null , 900); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership ("PendingLookup" " not thread-safe"); nsrefcnt count = ++mRefCnt ; NS_LogAddRef((this), (count), ("PendingLookup"), (uint32_t) (sizeof(*this))); return count; } MozExternalRefCountType PendingLookup ::Release(void) { do { static_assert( mozilla::detail::AssertionConditionType <decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0 ))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0" " (" "dup release" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0" ") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 900 ); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); do { static_assert( mozilla::detail::AssertionConditionType <decltype("PendingLookup" != nullptr)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!("PendingLookup" != nullptr)) ), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"PendingLookup\" != nullptr" " (" "Must specify a name" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr" ") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null , 900); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership ("PendingLookup" " not thread-safe"); const char* const nametmp = "PendingLookup"; nsrefcnt count = --mRefCnt; NS_LogRelease ((this), (count), (nametmp)); if (count == 0) { mRefCnt = 1; delete (this); return 0; } return count; } nsresult PendingLookup:: QueryInterface(const nsIID& aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!" , "aInstancePtr", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 900); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE ; static_assert(6 > 0, "Need more arguments to NS_INTERFACE_TABLE" ); static const QITableEntry table[] = { {&mozilla::detail ::kImplementedIID<PendingLookup, nsIStreamListener>, int32_t ( reinterpret_cast<char*>(static_cast<nsIStreamListener *>((PendingLookup*)0x1000)) - reinterpret_cast<char*> ((PendingLookup*)0x1000))}, {&mozilla::detail::kImplementedIID <PendingLookup, nsIRequestObserver>, int32_t( reinterpret_cast <char*>(static_cast<nsIRequestObserver*>((PendingLookup *)0x1000)) - reinterpret_cast<char*>((PendingLookup*)0x1000 ))}, {&mozilla::detail::kImplementedIID<PendingLookup, nsIObserver>, int32_t( reinterpret_cast<char*>(static_cast <nsIObserver*>((PendingLookup*)0x1000)) - reinterpret_cast <char*>((PendingLookup*)0x1000))}, {&mozilla::detail ::kImplementedIID<PendingLookup, nsISupportsWeakReference> , int32_t( reinterpret_cast<char*>(static_cast<nsISupportsWeakReference *>((PendingLookup*)0x1000)) - reinterpret_cast<char*> ((PendingLookup*)0x1000))}, {&mozilla::detail::kImplementedIID <PendingLookup, nsITimerCallback>, int32_t( reinterpret_cast <char*>(static_cast<nsITimerCallback*>((PendingLookup *)0x1000)) - reinterpret_cast<char*>((PendingLookup*)0x1000 ))}, {&mozilla::detail::kImplementedIID<PendingLookup, nsINamed>, int32_t( reinterpret_cast<char*>(static_cast <nsINamed*>((PendingLookup*)0x1000)) - reinterpret_cast <char*>((PendingLookup*)0x1000))}, {&mozilla::detail ::kImplementedIID<PendingLookup, nsISupports>, int32_t( reinterpret_cast<char*>(static_cast<nsISupports*> ( static_cast<nsIStreamListener*>((PendingLookup*)0x1000 ))) - reinterpret_cast<char*>((PendingLookup*)0x1000))} , { nullptr, 0 } } ; static_assert(std::size(table) > 1, "need at least 1 interface" ); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID , aInstancePtr, table); return rv; } |
| 899 | nsIObserver, nsISupportsWeakReference, nsITimerCallback,MozExternalRefCountType PendingLookup::AddRef(void) { static_assert (!std::is_destructible_v<PendingLookup>, "Reference-counted class " "PendingLookup" " should not have a public destructor. " "Make this class's destructor non-public" ); do { static_assert( mozilla::detail::AssertionConditionType <decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0" " (" "illegal refcnt" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0" ") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 900 ); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); do { static_assert( mozilla::detail::AssertionConditionType <decltype("PendingLookup" != nullptr)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!("PendingLookup" != nullptr)) ), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"PendingLookup\" != nullptr" " (" "Must specify a name" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr" ") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null , 900); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership ("PendingLookup" " not thread-safe"); nsrefcnt count = ++mRefCnt ; NS_LogAddRef((this), (count), ("PendingLookup"), (uint32_t) (sizeof(*this))); return count; } MozExternalRefCountType PendingLookup ::Release(void) { do { static_assert( mozilla::detail::AssertionConditionType <decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0 ))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0" " (" "dup release" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0" ") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 900 ); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); do { static_assert( mozilla::detail::AssertionConditionType <decltype("PendingLookup" != nullptr)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!("PendingLookup" != nullptr)) ), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"PendingLookup\" != nullptr" " (" "Must specify a name" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr" ") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null , 900); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership ("PendingLookup" " not thread-safe"); const char* const nametmp = "PendingLookup"; nsrefcnt count = --mRefCnt; NS_LogRelease ((this), (count), (nametmp)); if (count == 0) { mRefCnt = 1; delete (this); return 0; } return count; } nsresult PendingLookup:: QueryInterface(const nsIID& aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!" , "aInstancePtr", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 900); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE ; static_assert(6 > 0, "Need more arguments to NS_INTERFACE_TABLE" ); static const QITableEntry table[] = { {&mozilla::detail ::kImplementedIID<PendingLookup, nsIStreamListener>, int32_t ( reinterpret_cast<char*>(static_cast<nsIStreamListener *>((PendingLookup*)0x1000)) - reinterpret_cast<char*> ((PendingLookup*)0x1000))}, {&mozilla::detail::kImplementedIID <PendingLookup, nsIRequestObserver>, int32_t( reinterpret_cast <char*>(static_cast<nsIRequestObserver*>((PendingLookup *)0x1000)) - reinterpret_cast<char*>((PendingLookup*)0x1000 ))}, {&mozilla::detail::kImplementedIID<PendingLookup, nsIObserver>, int32_t( reinterpret_cast<char*>(static_cast <nsIObserver*>((PendingLookup*)0x1000)) - reinterpret_cast <char*>((PendingLookup*)0x1000))}, {&mozilla::detail ::kImplementedIID<PendingLookup, nsISupportsWeakReference> , int32_t( reinterpret_cast<char*>(static_cast<nsISupportsWeakReference *>((PendingLookup*)0x1000)) - reinterpret_cast<char*> ((PendingLookup*)0x1000))}, {&mozilla::detail::kImplementedIID <PendingLookup, nsITimerCallback>, int32_t( reinterpret_cast <char*>(static_cast<nsITimerCallback*>((PendingLookup *)0x1000)) - reinterpret_cast<char*>((PendingLookup*)0x1000 ))}, {&mozilla::detail::kImplementedIID<PendingLookup, nsINamed>, int32_t( reinterpret_cast<char*>(static_cast <nsINamed*>((PendingLookup*)0x1000)) - reinterpret_cast <char*>((PendingLookup*)0x1000))}, {&mozilla::detail ::kImplementedIID<PendingLookup, nsISupports>, int32_t( reinterpret_cast<char*>(static_cast<nsISupports*> ( static_cast<nsIStreamListener*>((PendingLookup*)0x1000 ))) - reinterpret_cast<char*>((PendingLookup*)0x1000))} , { nullptr, 0 } } ; static_assert(std::size(table) > 1, "need at least 1 interface" ); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID , aInstancePtr, table); return rv; } |
| 900 | nsINamed)MozExternalRefCountType PendingLookup::AddRef(void) { static_assert (!std::is_destructible_v<PendingLookup>, "Reference-counted class " "PendingLookup" " should not have a public destructor. " "Make this class's destructor non-public" ); do { static_assert( mozilla::detail::AssertionConditionType <decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0" " (" "illegal refcnt" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0" ") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 900 ); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); do { static_assert( mozilla::detail::AssertionConditionType <decltype("PendingLookup" != nullptr)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!("PendingLookup" != nullptr)) ), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"PendingLookup\" != nullptr" " (" "Must specify a name" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr" ") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null , 900); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership ("PendingLookup" " not thread-safe"); nsrefcnt count = ++mRefCnt ; NS_LogAddRef((this), (count), ("PendingLookup"), (uint32_t) (sizeof(*this))); return count; } MozExternalRefCountType PendingLookup ::Release(void) { do { static_assert( mozilla::detail::AssertionConditionType <decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0 ))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0" " (" "dup release" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0" ") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 900 ); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); do { static_assert( mozilla::detail::AssertionConditionType <decltype("PendingLookup" != nullptr)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!("PendingLookup" != nullptr)) ), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"PendingLookup\" != nullptr" " (" "Must specify a name" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr" ") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null , 900); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership ("PendingLookup" " not thread-safe"); const char* const nametmp = "PendingLookup"; nsrefcnt count = --mRefCnt; NS_LogRelease ((this), (count), (nametmp)); if (count == 0) { mRefCnt = 1; delete (this); return 0; } return count; } nsresult PendingLookup:: QueryInterface(const nsIID& aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!" , "aInstancePtr", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 900); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE ; static_assert(6 > 0, "Need more arguments to NS_INTERFACE_TABLE" ); static const QITableEntry table[] = { {&mozilla::detail ::kImplementedIID<PendingLookup, nsIStreamListener>, int32_t ( reinterpret_cast<char*>(static_cast<nsIStreamListener *>((PendingLookup*)0x1000)) - reinterpret_cast<char*> ((PendingLookup*)0x1000))}, {&mozilla::detail::kImplementedIID <PendingLookup, nsIRequestObserver>, int32_t( reinterpret_cast <char*>(static_cast<nsIRequestObserver*>((PendingLookup *)0x1000)) - reinterpret_cast<char*>((PendingLookup*)0x1000 ))}, {&mozilla::detail::kImplementedIID<PendingLookup, nsIObserver>, int32_t( reinterpret_cast<char*>(static_cast <nsIObserver*>((PendingLookup*)0x1000)) - reinterpret_cast <char*>((PendingLookup*)0x1000))}, {&mozilla::detail ::kImplementedIID<PendingLookup, nsISupportsWeakReference> , int32_t( reinterpret_cast<char*>(static_cast<nsISupportsWeakReference *>((PendingLookup*)0x1000)) - reinterpret_cast<char*> ((PendingLookup*)0x1000))}, {&mozilla::detail::kImplementedIID <PendingLookup, nsITimerCallback>, int32_t( reinterpret_cast <char*>(static_cast<nsITimerCallback*>((PendingLookup *)0x1000)) - reinterpret_cast<char*>((PendingLookup*)0x1000 ))}, {&mozilla::detail::kImplementedIID<PendingLookup, nsINamed>, int32_t( reinterpret_cast<char*>(static_cast <nsINamed*>((PendingLookup*)0x1000)) - reinterpret_cast <char*>((PendingLookup*)0x1000))}, {&mozilla::detail ::kImplementedIID<PendingLookup, nsISupports>, int32_t( reinterpret_cast<char*>(static_cast<nsISupports*> ( static_cast<nsIStreamListener*>((PendingLookup*)0x1000 ))) - reinterpret_cast<char*>((PendingLookup*)0x1000))} , { nullptr, 0 } } ; static_assert(std::size(table) > 1, "need at least 1 interface" ); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID , aInstancePtr, table); return rv; } |
| 901 | |
| 902 | PendingLookup::PendingLookup(nsIApplicationReputationQuery* aQuery, |
| 903 | nsIApplicationReputationCallback* aCallback) |
| 904 | : mIsBinaryFile(false), |
| 905 | mBlocklistCount(0), |
| 906 | mAllowlistCount(0), |
| 907 | mQuery(aQuery), |
| 908 | mCallback(aCallback) { |
| 909 | LOG(("Created pending lookup [this = %p]", this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Created pending lookup [this = %p]" , this); } } while (0); |
| 910 | } |
| 911 | |
| 912 | PendingLookup::~PendingLookup() { |
| 913 | LOG(("Destroying pending lookup [this = %p]", this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Destroying pending lookup [this = %p]" , this); } } while (0); |
| 914 | } |
| 915 | |
| 916 | static const char* const kDmgFileExtensions[] = { |
| 917 | ".cdr", ".dart", ".dc42", ".diskcopy42", |
| 918 | ".dmg", ".dmgpart", ".dvdr", ".img", |
| 919 | ".imgpart", ".iso", ".ndif", ".smi", |
| 920 | ".sparsebundle", ".sparseimage", ".toast", ".udif", |
| 921 | }; |
| 922 | |
| 923 | static const char* const kRarFileExtensions[] = { |
| 924 | ".r00", ".r01", ".r02", ".r03", ".r04", ".r05", ".r06", ".r07", |
| 925 | ".r08", ".r09", ".r10", ".r11", ".r12", ".r13", ".r14", ".r15", |
| 926 | ".r16", ".r17", ".r18", ".r19", ".r20", ".r21", ".r22", ".r23", |
| 927 | ".r24", ".r25", ".r26", ".r27", ".r28", ".r29", ".rar", |
| 928 | }; |
| 929 | |
| 930 | static const char* const kZipFileExtensions[] = { |
| 931 | ".zip", // Generic archive |
| 932 | ".zipx", // WinZip |
| 933 | }; |
| 934 | |
| 935 | static const char* GetFileExt(const nsACString& aFilename, |
| 936 | const char* const aFileExtensions[], |
| 937 | const size_t aLength) { |
| 938 | for (size_t i = 0; i < aLength; ++i) { |
| 939 | if (StringEndsWith(aFilename, nsDependentCString(aFileExtensions[i]), |
| 940 | nsCaseInsensitiveCStringComparator)) { |
| 941 | return aFileExtensions[i]; |
| 942 | } |
| 943 | } |
| 944 | return nullptr; |
| 945 | } |
| 946 | |
| 947 | static const char* GetFileExt(const nsACString& aFilename) { |
| 948 | #define _GetFileExt(_f, _l)GetFileExt(_f, _l, std::size(_l)) GetFileExt(_f, _l, std::size(_l)) |
| 949 | const char* ext = _GetFileExt(GetFileExt(aFilename, ApplicationReputationService::kBinaryFileExtensions , std::size(ApplicationReputationService::kBinaryFileExtensions )) |
| 950 | aFilename, ApplicationReputationService::kBinaryFileExtensions)GetFileExt(aFilename, ApplicationReputationService::kBinaryFileExtensions , std::size(ApplicationReputationService::kBinaryFileExtensions )); |
| 951 | if (ext == nullptr && |
| 952 | !_GetFileExt(aFilename,GetFileExt(aFilename, ApplicationReputationService::kNonBinaryExecutables , std::size(ApplicationReputationService::kNonBinaryExecutables )) |
| 953 | ApplicationReputationService::kNonBinaryExecutables)GetFileExt(aFilename, ApplicationReputationService::kNonBinaryExecutables , std::size(ApplicationReputationService::kNonBinaryExecutables ))) { |
| 954 | ext = _GetFileExt(aFilename, sExecutableExts)GetFileExt(aFilename, sExecutableExts, std::size(sExecutableExts )); |
| 955 | } |
| 956 | return ext; |
| 957 | } |
| 958 | |
| 959 | // Returns true if the file extension matches one in the given array. |
| 960 | static bool IsFileType(const nsACString& aFilename, |
| 961 | const char* const aFileExtensions[], |
| 962 | const size_t aLength) { |
| 963 | return GetFileExt(aFilename, aFileExtensions, aLength) != nullptr; |
| 964 | } |
| 965 | |
| 966 | static bool IsBinary(const nsACString& aFilename) { |
| 967 | return IsFileType( |
| 968 | aFilename, ApplicationReputationService::kBinaryFileExtensions, |
| 969 | std::size(ApplicationReputationService::kBinaryFileExtensions)) || |
| 970 | (!IsFileType( |
| 971 | aFilename, ApplicationReputationService::kNonBinaryExecutables, |
| 972 | std::size(ApplicationReputationService::kNonBinaryExecutables)) && |
| 973 | IsFileType(aFilename, sExecutableExts, std::size(sExecutableExts))); |
| 974 | } |
| 975 | |
| 976 | ClientDownloadRequest::DownloadType PendingLookup::GetDownloadType( |
| 977 | const nsACString& aFilename) { |
| 978 | MOZ_ASSERT(IsBinary(aFilename))do { static_assert( mozilla::detail::AssertionConditionType< decltype(IsBinary(aFilename))>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(IsBinary(aFilename)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("IsBinary(aFilename)" , "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 978); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsBinary(aFilename)" ")"); do { MOZ_CrashSequence(__null, 978); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
| 979 | |
| 980 | // Extensions are matched case-insensitively, so compare against a lowercased |
| 981 | // copy of the filename. |
| 982 | nsAutoCString fileName(aFilename); |
| 983 | ToLowerCase(fileName); |
| 984 | |
| 985 | // From |
| 986 | // https://cs.chromium.org/chromium/src/chrome/common/safe_browsing/download_protection_util.cc?l=17 |
| 987 | if (StringEndsWith(fileName, ".zip"_ns)) { |
| 988 | return ClientDownloadRequest::ZIPPED_EXECUTABLE; |
| 989 | } else if (StringEndsWith(fileName, ".apk"_ns)) { |
| 990 | return ClientDownloadRequest::ANDROID_APK; |
| 991 | } else if (StringEndsWith(fileName, ".app"_ns) || |
| 992 | StringEndsWith(fileName, ".applescript"_ns) || |
| 993 | StringEndsWith(fileName, ".cdr"_ns) || |
| 994 | StringEndsWith(fileName, ".dart"_ns) || |
| 995 | StringEndsWith(fileName, ".dc42"_ns) || |
| 996 | StringEndsWith(fileName, ".diskcopy42"_ns) || |
| 997 | StringEndsWith(fileName, ".dmg"_ns) || |
| 998 | StringEndsWith(fileName, ".dmgpart"_ns) || |
| 999 | StringEndsWith(fileName, ".dvdr"_ns) || |
| 1000 | StringEndsWith(fileName, ".img"_ns) || |
| 1001 | StringEndsWith(fileName, ".imgpart"_ns) || |
| 1002 | StringEndsWith(fileName, ".iso"_ns) || |
| 1003 | StringEndsWith(fileName, ".mpkg"_ns) || |
| 1004 | StringEndsWith(fileName, ".ndif"_ns) || |
| 1005 | StringEndsWith(fileName, ".osas"_ns) || |
| 1006 | StringEndsWith(fileName, ".osax"_ns) || |
| 1007 | StringEndsWith(fileName, ".pkg"_ns) || |
| 1008 | StringEndsWith(fileName, ".scpt"_ns) || |
| 1009 | StringEndsWith(fileName, ".scptd"_ns) || |
| 1010 | StringEndsWith(fileName, ".seplugin"_ns) || |
| 1011 | StringEndsWith(fileName, ".smi"_ns) || |
| 1012 | StringEndsWith(fileName, ".sparsebundle"_ns) || |
| 1013 | StringEndsWith(fileName, ".sparseimage"_ns) || |
| 1014 | StringEndsWith(fileName, ".toast"_ns) || |
| 1015 | StringEndsWith(fileName, ".udif"_ns)) { |
| 1016 | return ClientDownloadRequest::MAC_EXECUTABLE; |
| 1017 | } |
| 1018 | |
| 1019 | return ClientDownloadRequest::WIN_EXECUTABLE; // default to Windows binaries |
| 1020 | } |
| 1021 | |
| 1022 | nsresult PendingLookup::LookupNext() { |
| 1023 | // We must call LookupNext or SendRemoteQuery upon return. |
| 1024 | // Look up all of the URLs that could allow or block this download. |
| 1025 | // Blocklist first. |
| 1026 | |
| 1027 | // If a url is in blocklist we should call PendingLookup::OnComplete directly. |
| 1028 | MOZ_ASSERT(mBlocklistCount == 0)do { static_assert( mozilla::detail::AssertionConditionType< decltype(mBlocklistCount == 0)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(mBlocklistCount == 0))), 0)) ) { do { } while (false); MOZ_ReportAssertionFailure("mBlocklistCount == 0" , "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1028); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mBlocklistCount == 0" ")"); do { MOZ_CrashSequence(__null, 1028); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
| 1029 | |
| 1030 | nsCString spec; |
| 1031 | if (!mAnylistSpecs.IsEmpty()) { |
| 1032 | // Check the source URI only. |
| 1033 | spec = mAnylistSpecs.PopLastElement(); |
| 1034 | RefPtr<PendingDBLookup> lookup(new PendingDBLookup(this)); |
| 1035 | |
| 1036 | // We don't need to check whitelist if the file is not a binary file. |
| 1037 | auto type = |
| 1038 | mIsBinaryFile ? LookupType::BothLists : LookupType::BlocklistOnly; |
| 1039 | return lookup->LookupSpec(spec, type); |
| 1040 | } |
| 1041 | |
| 1042 | if (!mBlocklistSpecs.IsEmpty()) { |
| 1043 | // Check the referrer and redirect chain. |
| 1044 | spec = mBlocklistSpecs.PopLastElement(); |
| 1045 | RefPtr<PendingDBLookup> lookup(new PendingDBLookup(this)); |
| 1046 | return lookup->LookupSpec(spec, LookupType::BlocklistOnly); |
| 1047 | } |
| 1048 | |
| 1049 | // Now that we've looked up all of the URIs against the blocklist, |
| 1050 | // if any of mAnylistSpecs or mAllowlistSpecs matched the allowlist, |
| 1051 | // go ahead and pass. |
| 1052 | if (mAllowlistCount > 0) { |
| 1053 | return OnComplete(nsIApplicationReputationService::VERDICT_SAFE, |
| 1054 | Reason::eLocalwhitelist, NS_OK); |
| 1055 | } |
| 1056 | |
| 1057 | MOZ_ASSERT_IF(!mIsBinaryFile, mAllowlistSpecs.Length() == 0)do { if (!mIsBinaryFile) { do { static_assert( mozilla::detail ::AssertionConditionType<decltype(mAllowlistSpecs.Length() == 0)>::isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!(mAllowlistSpecs.Length() == 0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("mAllowlistSpecs.Length() == 0" , "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1057); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAllowlistSpecs.Length() == 0" ")"); do { MOZ_CrashSequence(__null, 1057); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); } } while ( false); |
| 1058 | |
| 1059 | // Only binary signatures remain. |
| 1060 | if (!mAllowlistSpecs.IsEmpty()) { |
| 1061 | spec = mAllowlistSpecs.PopLastElement(); |
| 1062 | LOG(("PendingLookup::LookupNext: checking %s on allowlist", spec.get()))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::LookupNext: checking %s on allowlist" , spec.get()); } } while (0); |
| 1063 | RefPtr<PendingDBLookup> lookup(new PendingDBLookup(this)); |
| 1064 | return lookup->LookupSpec(spec, LookupType::AllowlistOnly); |
| 1065 | } |
| 1066 | |
| 1067 | if (!mFileName.IsEmpty()) { |
| 1068 | if (IsBinary(mFileName)) { |
| 1069 | mozilla::glean::application_reputation::binary_type |
| 1070 | .EnumGet(mozilla::glean::application_reputation::BinaryTypeLabel:: |
| 1071 | eBinaryfile) |
| 1072 | .Add(); |
| 1073 | } else if (IsFileType(mFileName, kSafeFileExtensions, |
| 1074 | std::size(kSafeFileExtensions))) { |
| 1075 | mozilla::glean::application_reputation::binary_type |
| 1076 | .EnumGet(mozilla::glean::application_reputation::BinaryTypeLabel:: |
| 1077 | eNonbinaryfile) |
| 1078 | .Add(); |
| 1079 | } else if (IsFileType(mFileName, kMozNonBinaryExecutables, |
| 1080 | std::size(kMozNonBinaryExecutables))) { |
| 1081 | mozilla::glean::application_reputation::binary_type |
| 1082 | .EnumGet(mozilla::glean::application_reputation::BinaryTypeLabel:: |
| 1083 | eMoznonbinaryfile) |
| 1084 | .Add(); |
| 1085 | } else { |
| 1086 | mozilla::glean::application_reputation::binary_type |
| 1087 | .EnumGet(mozilla::glean::application_reputation::BinaryTypeLabel:: |
| 1088 | eUnknownfile) |
| 1089 | .Add(); |
| 1090 | } |
| 1091 | } else { |
| 1092 | mozilla::glean::application_reputation::binary_type |
| 1093 | .EnumGet(mozilla::glean::application_reputation::BinaryTypeLabel:: |
| 1094 | eMissingfilename) |
| 1095 | .Add(); |
| 1096 | } |
| 1097 | |
| 1098 | if (IsFileType(mFileName, kDmgFileExtensions, |
| 1099 | std::size(kDmgFileExtensions))) { |
| 1100 | mozilla::glean::application_reputation::binary_archive |
| 1101 | .EnumGet(mozilla::glean::application_reputation::BinaryArchiveLabel:: |
| 1102 | eDmgfile) |
| 1103 | .Add(); |
| 1104 | } else if (IsFileType(mFileName, kRarFileExtensions, |
| 1105 | std::size(kRarFileExtensions))) { |
| 1106 | mozilla::glean::application_reputation::binary_archive |
| 1107 | .EnumGet(mozilla::glean::application_reputation::BinaryArchiveLabel:: |
| 1108 | eRarfile) |
| 1109 | .Add(); |
| 1110 | } else if (IsFileType(mFileName, kZipFileExtensions, |
| 1111 | std::size(kZipFileExtensions))) { |
| 1112 | mozilla::glean::application_reputation::binary_archive |
| 1113 | .EnumGet(mozilla::glean::application_reputation::BinaryArchiveLabel:: |
| 1114 | eZipfile) |
| 1115 | .Add(); |
| 1116 | } else if (mIsBinaryFile) { |
| 1117 | mozilla::glean::application_reputation::binary_archive |
| 1118 | .EnumGet(mozilla::glean::application_reputation::BinaryArchiveLabel:: |
| 1119 | eOtherbinaryfile) |
| 1120 | .Add(); |
| 1121 | } |
| 1122 | |
| 1123 | // There are no more URIs to check against local list. If the file is |
| 1124 | // not eligible for remote lookup, bail. |
| 1125 | if (!mIsBinaryFile) { |
| 1126 | LOG(("Not eligible for remote lookups [this=%p]", this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Not eligible for remote lookups [this=%p]" , this); } } while (0); |
| 1127 | return OnComplete(nsIApplicationReputationService::VERDICT_SAFE, |
| 1128 | Reason::eNonbinaryfile, NS_OK); |
| 1129 | } |
| 1130 | |
| 1131 | nsresult rv = SendRemoteQuery(); |
| 1132 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
| 1133 | return OnComplete(nsIApplicationReputationService::VERDICT_SAFE, |
| 1134 | Reason::eInternalerror, rv); |
| 1135 | } |
| 1136 | return NS_OK; |
| 1137 | } |
| 1138 | |
| 1139 | nsCString PendingLookup::EscapeCertificateAttribute( |
| 1140 | const nsACString& aAttribute) { |
| 1141 | // Escape '/' because it's a field separator, and '%' because Chrome does |
| 1142 | nsCString escaped; |
| 1143 | escaped.SetCapacity(aAttribute.Length()); |
| 1144 | for (unsigned int i = 0; i < aAttribute.Length(); ++i) { |
| 1145 | if (aAttribute.Data()[i] == '%') { |
| 1146 | escaped.AppendLiteral("%25"); |
| 1147 | } else if (aAttribute.Data()[i] == '/') { |
| 1148 | escaped.AppendLiteral("%2F"); |
| 1149 | } else if (aAttribute.Data()[i] == ' ') { |
| 1150 | escaped.AppendLiteral("%20"); |
| 1151 | } else { |
| 1152 | escaped.Append(aAttribute.Data()[i]); |
| 1153 | } |
| 1154 | } |
| 1155 | return escaped; |
| 1156 | } |
| 1157 | |
| 1158 | nsCString PendingLookup::EscapeFingerprint(const nsACString& aFingerprint) { |
| 1159 | // Google's fingerprint doesn't have colons |
| 1160 | nsCString escaped; |
| 1161 | escaped.SetCapacity(aFingerprint.Length()); |
| 1162 | for (unsigned int i = 0; i < aFingerprint.Length(); ++i) { |
| 1163 | if (aFingerprint.Data()[i] != ':') { |
| 1164 | escaped.Append(aFingerprint.Data()[i]); |
| 1165 | } |
| 1166 | } |
| 1167 | return escaped; |
| 1168 | } |
| 1169 | |
| 1170 | nsresult PendingLookup::GenerateWhitelistStringsForPair( |
| 1171 | nsIX509Cert* certificate, nsIX509Cert* issuer) { |
| 1172 | // The whitelist paths have format: |
| 1173 | // http://sb-ssl.google.com/safebrowsing/csd/certificate/<issuer_cert_fingerprint>[/CN=<cn>][/O=<org>][/OU=<unit>] |
| 1174 | // Any of CN, O, or OU may be omitted from the whitelist entry. Unfortunately |
| 1175 | // this is not publicly documented, but the Chrome implementation can be found |
| 1176 | // here: |
| 1177 | // https://code.google.com/p/chromium/codesearch#search/&q=GetCertificateWhitelistStrings |
| 1178 | nsCString whitelistString( |
| 1179 | "http://sb-ssl.google.com/safebrowsing/csd/certificate/"); |
| 1180 | |
| 1181 | nsString fingerprint; |
| 1182 | nsresult rv = issuer->GetSha1Fingerprint(fingerprint); |
| 1183 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1183); return rv; } } while (false); |
| 1184 | whitelistString.Append(EscapeFingerprint(NS_ConvertUTF16toUTF8(fingerprint))); |
| 1185 | |
| 1186 | nsString commonName; |
| 1187 | rv = certificate->GetCommonName(commonName); |
| 1188 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1188); return rv; } } while (false); |
| 1189 | if (!commonName.IsEmpty()) { |
| 1190 | whitelistString.AppendLiteral("/CN="); |
| 1191 | whitelistString.Append( |
| 1192 | EscapeCertificateAttribute(NS_ConvertUTF16toUTF8(commonName))); |
| 1193 | } |
| 1194 | |
| 1195 | nsString organization; |
| 1196 | rv = certificate->GetOrganization(organization); |
| 1197 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1197); return rv; } } while (false); |
| 1198 | if (!organization.IsEmpty()) { |
| 1199 | whitelistString.AppendLiteral("/O="); |
| 1200 | whitelistString.Append( |
| 1201 | EscapeCertificateAttribute(NS_ConvertUTF16toUTF8(organization))); |
| 1202 | } |
| 1203 | |
| 1204 | nsString organizationalUnit; |
| 1205 | rv = certificate->GetOrganizationalUnit(organizationalUnit); |
| 1206 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1206); return rv; } } while (false); |
| 1207 | if (!organizationalUnit.IsEmpty()) { |
| 1208 | whitelistString.AppendLiteral("/OU="); |
| 1209 | whitelistString.Append( |
| 1210 | EscapeCertificateAttribute(NS_ConvertUTF16toUTF8(organizationalUnit))); |
| 1211 | } |
| 1212 | LOG(("Whitelisting %s", whitelistString.get()))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Whitelisting %s" , whitelistString.get()); } } while (0); |
| 1213 | |
| 1214 | mAllowlistSpecs.AppendElement(whitelistString); |
| 1215 | return NS_OK; |
| 1216 | } |
| 1217 | |
| 1218 | nsresult PendingLookup::GenerateWhitelistStringsForChain( |
| 1219 | const safe_browsing::ClientDownloadRequest_CertificateChain& aChain) { |
| 1220 | // We need a signing certificate and an issuer to construct a whitelist |
| 1221 | // entry. |
| 1222 | if (aChain.element_size() < 2) { |
| 1223 | return NS_OK; |
| 1224 | } |
| 1225 | |
| 1226 | // Get the signer. |
| 1227 | nsresult rv; |
| 1228 | nsCOMPtr<nsIX509CertDB> certDB = do_GetService(NS_X509CERTDB_CONTRACTID"@mozilla.org/security/x509certdb;1", &rv); |
| 1229 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1229); return rv; } } while (false); |
| 1230 | |
| 1231 | nsCOMPtr<nsIX509Cert> signer; |
| 1232 | nsTArray<uint8_t> signerBytes; |
| 1233 | signerBytes.AppendElements(aChain.element(0).certificate().data(), |
| 1234 | aChain.element(0).certificate().size()); |
| 1235 | rv = certDB->ConstructX509(signerBytes, getter_AddRefs(signer)); |
| 1236 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1236); return rv; } } while (false); |
| 1237 | |
| 1238 | for (int i = 1; i < aChain.element_size(); ++i) { |
| 1239 | // Get the issuer. |
| 1240 | nsCOMPtr<nsIX509Cert> issuer; |
| 1241 | nsTArray<uint8_t> issuerBytes; |
| 1242 | issuerBytes.AppendElements(aChain.element(i).certificate().data(), |
| 1243 | aChain.element(i).certificate().size()); |
| 1244 | rv = certDB->ConstructX509(issuerBytes, getter_AddRefs(issuer)); |
| 1245 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1245); return rv; } } while (false); |
| 1246 | |
| 1247 | rv = GenerateWhitelistStringsForPair(signer, issuer); |
| 1248 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1248); return rv; } } while (false); |
| 1249 | } |
| 1250 | return NS_OK; |
| 1251 | } |
| 1252 | |
| 1253 | nsresult PendingLookup::GenerateWhitelistStrings() { |
| 1254 | for (int i = 0; i < mRequest.signature().certificate_chain_size(); ++i) { |
| 1255 | nsresult rv = GenerateWhitelistStringsForChain( |
| 1256 | mRequest.signature().certificate_chain(i)); |
| 1257 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1257); return rv; } } while (false); |
| 1258 | } |
| 1259 | return NS_OK; |
| 1260 | } |
| 1261 | |
| 1262 | nsresult PendingLookup::AddRedirects(nsIArray* aRedirects) { |
| 1263 | uint32_t length = 0; |
| 1264 | aRedirects->GetLength(&length); |
| 1265 | LOG(("ApplicationReputation: Got %u redirects", length))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "ApplicationReputation: Got %u redirects" , length); } } while (0); |
| 1266 | nsCOMPtr<nsISimpleEnumerator> iter; |
| 1267 | nsresult rv = aRedirects->Enumerate(getter_AddRefs(iter)); |
| 1268 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1268); return rv; } } while (false); |
| 1269 | |
| 1270 | bool hasMoreRedirects = false; |
| 1271 | rv = iter->HasMoreElements(&hasMoreRedirects); |
| 1272 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1272); return rv; } } while (false); |
| 1273 | |
| 1274 | while (hasMoreRedirects) { |
| 1275 | nsCOMPtr<nsISupports> supports; |
| 1276 | rv = iter->GetNext(getter_AddRefs(supports)); |
| 1277 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1277); return rv; } } while (false); |
| 1278 | |
| 1279 | nsCOMPtr<nsIRedirectHistoryEntry> redirectEntry = |
| 1280 | do_QueryInterface(supports, &rv); |
| 1281 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1281); return rv; } } while (false); |
| 1282 | |
| 1283 | nsCOMPtr<nsIPrincipal> principal; |
| 1284 | rv = redirectEntry->GetPrincipal(getter_AddRefs(principal)); |
| 1285 | auto* basePrin = BasePrincipal::Cast(principal); |
| 1286 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1286); return rv; } } while (false); |
| 1287 | |
| 1288 | nsCOMPtr<nsIURI> uri; |
| 1289 | rv = basePrin->GetURI(getter_AddRefs(uri)); |
| 1290 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1290); return rv; } } while (false); |
| 1291 | |
| 1292 | // Add the spec to our list of local lookups. The most recent redirect is |
| 1293 | // the last element. |
| 1294 | nsCString spec; |
| 1295 | rv = GetStrippedSpec(uri, spec); |
| 1296 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1296); return rv; } } while (false); |
| 1297 | mBlocklistSpecs.AppendElement(spec); |
| 1298 | LOG(("ApplicationReputation: Appending redirect %s\n", spec.get()))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "ApplicationReputation: Appending redirect %s\n" , spec.get()); } } while (0); |
| 1299 | |
| 1300 | // Store the redirect information in the remote request. |
| 1301 | ClientDownloadRequest_Resource* resource = mRequest.add_resources(); |
| 1302 | resource->set_url(spec.get()); |
| 1303 | resource->set_type(ClientDownloadRequest::DOWNLOAD_REDIRECT); |
| 1304 | |
| 1305 | rv = iter->HasMoreElements(&hasMoreRedirects); |
| 1306 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1306); return rv; } } while (false); |
| 1307 | } |
| 1308 | return NS_OK; |
| 1309 | } |
| 1310 | |
| 1311 | nsresult PendingLookup::StartLookup() { |
| 1312 | mStartTime = TimeStamp::Now(); |
| 1313 | nsresult rv = DoLookupInternal(); |
| 1314 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
| 1315 | return OnComplete(nsIApplicationReputationService::VERDICT_SAFE, |
| 1316 | Reason::eInternalerror, NS_OK); |
| 1317 | } |
| 1318 | return rv; |
| 1319 | } |
| 1320 | |
| 1321 | nsresult PendingLookup::GetSpecHash(nsACString& aSpec, |
| 1322 | nsACString& hexEncodedHash) { |
| 1323 | nsCOMPtr<nsICryptoHash> cryptoHash; |
| 1324 | nsresult rv = |
| 1325 | NS_NewCryptoHash(nsICryptoHash::SHA256, getter_AddRefs(cryptoHash)); |
| 1326 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1326); return rv; } } while (false); |
| 1327 | |
| 1328 | rv = cryptoHash->Update( |
| 1329 | reinterpret_cast<const uint8_t*>(aSpec.BeginReading()), aSpec.Length()); |
| 1330 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1330); return rv; } } while (false); |
| 1331 | |
| 1332 | nsAutoCString binaryHash; |
| 1333 | rv = cryptoHash->Finish(false, binaryHash); |
| 1334 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1334); return rv; } } while (false); |
| 1335 | |
| 1336 | // This needs to match HexEncode() in Chrome's |
| 1337 | // src/base/strings/string_number_conversions.cc |
| 1338 | static const char* const hex = "0123456789ABCDEF"; |
| 1339 | hexEncodedHash.SetCapacity(2 * binaryHash.Length()); |
| 1340 | for (size_t i = 0; i < binaryHash.Length(); ++i) { |
| 1341 | auto c = static_cast<unsigned char>(binaryHash[i]); |
| 1342 | hexEncodedHash.Append(hex[(c >> 4) & 0x0F]); |
| 1343 | hexEncodedHash.Append(hex[c & 0x0F]); |
| 1344 | } |
| 1345 | |
| 1346 | return NS_OK; |
| 1347 | } |
| 1348 | |
| 1349 | nsresult PendingLookup::GetStrippedSpec(nsIURI* aUri, nsACString& escaped) { |
| 1350 | if (NS_WARN_IF(!aUri)NS_warn_if_impl(!aUri, "!aUri", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1350)) { |
| 1351 | return NS_ERROR_INVALID_ARG; |
| 1352 | } |
| 1353 | |
| 1354 | nsresult rv; |
| 1355 | rv = aUri->GetScheme(escaped); |
| 1356 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1356); return rv; } } while (false); |
| 1357 | |
| 1358 | if (escaped.EqualsLiteral("blob")) { |
| 1359 | aUri->GetSpec(escaped); |
| 1360 | LOG(do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): blob URL left unstripped as '%s' " "[this = %p]", TPromiseFlatString<char>(escaped).get() , this); } } while (0) |
| 1361 | ("PendingLookup::GetStrippedSpec(): blob URL left unstripped as '%s' "do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): blob URL left unstripped as '%s' " "[this = %p]", TPromiseFlatString<char>(escaped).get() , this); } } while (0) |
| 1362 | "[this = %p]",do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): blob URL left unstripped as '%s' " "[this = %p]", TPromiseFlatString<char>(escaped).get() , this); } } while (0) |
| 1363 | PromiseFlatCString(escaped).get(), this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): blob URL left unstripped as '%s' " "[this = %p]", TPromiseFlatString<char>(escaped).get() , this); } } while (0); |
| 1364 | return NS_OK; |
| 1365 | } |
| 1366 | |
| 1367 | if (escaped.EqualsLiteral("data")) { |
| 1368 | // Replace URI with "data:<everything before comma>,SHA256(<whole URI>)" |
| 1369 | aUri->GetSpec(escaped); |
| 1370 | int32_t comma = escaped.FindChar(','); |
| 1371 | if (comma > -1 && |
| 1372 | static_cast<nsCString::size_type>(comma) < escaped.Length() - 1) { |
| 1373 | MOZ_ASSERT(comma > 4, "Data URIs start with 'data:'")do { static_assert( mozilla::detail::AssertionConditionType< decltype(comma > 4)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(comma > 4))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("comma > 4" " (" "Data URIs start with 'data:'" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1373); AnnotateMozCrashReason("MOZ_ASSERT" "(" "comma > 4" ") (" "Data URIs start with 'data:'" ")"); do { MOZ_CrashSequence (__null, 1373); __attribute__((nomerge)) ::abort(); } while ( false); } } while (false); |
| 1374 | nsAutoCString hexEncodedHash; |
| 1375 | rv = GetSpecHash(escaped, hexEncodedHash); |
| 1376 | if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) { |
| 1377 | escaped.Truncate(comma + 1); |
| 1378 | escaped.Append(hexEncodedHash); |
| 1379 | } |
| 1380 | } |
| 1381 | |
| 1382 | LOG(do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): data URL stripped to '%s' [this = " "%p]", TPromiseFlatString<char>(escaped).get(), this); } } while (0) |
| 1383 | ("PendingLookup::GetStrippedSpec(): data URL stripped to '%s' [this = "do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): data URL stripped to '%s' [this = " "%p]", TPromiseFlatString<char>(escaped).get(), this); } } while (0) |
| 1384 | "%p]",do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): data URL stripped to '%s' [this = " "%p]", TPromiseFlatString<char>(escaped).get(), this); } } while (0) |
| 1385 | PromiseFlatCString(escaped).get(), this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): data URL stripped to '%s' [this = " "%p]", TPromiseFlatString<char>(escaped).get(), this); } } while (0); |
| 1386 | return NS_OK; |
| 1387 | } |
| 1388 | |
| 1389 | // If aURI is not an nsIURL, we do not want to check the lists or send a |
| 1390 | // remote query. |
| 1391 | nsCOMPtr<nsIURL> url = do_QueryInterface(aUri, &rv); |
| 1392 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
| 1393 | LOG(do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): scheme '%s' is not supported [this " "= %p]", TPromiseFlatString<char>(escaped).get(), this ); } } while (0) |
| 1394 | ("PendingLookup::GetStrippedSpec(): scheme '%s' is not supported [this "do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): scheme '%s' is not supported [this " "= %p]", TPromiseFlatString<char>(escaped).get(), this ); } } while (0) |
| 1395 | "= %p]",do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): scheme '%s' is not supported [this " "= %p]", TPromiseFlatString<char>(escaped).get(), this ); } } while (0) |
| 1396 | PromiseFlatCString(escaped).get(), this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): scheme '%s' is not supported [this " "= %p]", TPromiseFlatString<char>(escaped).get(), this ); } } while (0); |
| 1397 | return rv; |
| 1398 | } |
| 1399 | |
| 1400 | nsCString temp; |
| 1401 | rv = url->GetHostPort(temp); |
| 1402 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1402); return rv; } } while (false); |
| 1403 | |
| 1404 | escaped.AppendLiteral("://"); |
| 1405 | escaped.Append(temp); |
| 1406 | |
| 1407 | rv = url->GetFilePath(temp); |
| 1408 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1408); return rv; } } while (false); |
| 1409 | |
| 1410 | // nsIUrl.filePath starts with '/' |
| 1411 | escaped.Append(temp); |
| 1412 | |
| 1413 | LOG(("PendingLookup::GetStrippedSpec(): URL stripped to '%s' [this = %p]",do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): URL stripped to '%s' [this = %p]" , TPromiseFlatString<char>(escaped).get(), this); } } while (0) |
| 1414 | PromiseFlatCString(escaped).get(), this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): URL stripped to '%s' [this = %p]" , TPromiseFlatString<char>(escaped).get(), this); } } while (0); |
| 1415 | return NS_OK; |
| 1416 | } |
| 1417 | |
| 1418 | nsresult PendingLookup::DoLookupInternal() { |
| 1419 | // We want to check the target URI, its referrer, and associated redirects |
| 1420 | // against the local lists. |
| 1421 | nsCOMPtr<nsIURI> uri; |
| 1422 | nsresult rv = mQuery->GetSourceURI(getter_AddRefs(uri)); |
| 1423 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1423); return rv; } } while (false); |
| 1424 | |
| 1425 | nsCString sourceSpec; |
| 1426 | rv = GetStrippedSpec(uri, sourceSpec); |
| 1427 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1427); return rv; } } while (false); |
| 1428 | |
| 1429 | mAnylistSpecs.AppendElement(sourceSpec); |
| 1430 | |
| 1431 | ClientDownloadRequest_Resource* resource = mRequest.add_resources(); |
| 1432 | resource->set_url(sourceSpec.get()); |
| 1433 | resource->set_type(ClientDownloadRequest::DOWNLOAD_URL); |
| 1434 | |
| 1435 | nsCOMPtr<nsIReferrerInfo> referrerInfo; |
| 1436 | (void)mQuery->GetReferrerInfo(getter_AddRefs(referrerInfo)); |
| 1437 | nsCOMPtr<nsIURI> referrer; |
| 1438 | // It is quite possible that referrer header is omitted due to security reason |
| 1439 | // (for example navigation from https-> http). Hence we should use the |
| 1440 | // original referrer which has not applied referrer policy yet, to make sure |
| 1441 | // we don't mistakenly allow unsafe download. |
| 1442 | if (referrerInfo) { |
| 1443 | referrer = referrerInfo->GetOriginalReferrer(); |
| 1444 | } |
| 1445 | |
| 1446 | if (referrer) { |
| 1447 | nsCString referrerSpec; |
| 1448 | rv = GetStrippedSpec(referrer, referrerSpec); |
| 1449 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1449); return rv; } } while (false); |
| 1450 | mBlocklistSpecs.AppendElement(referrerSpec); |
| 1451 | resource->set_referrer(referrerSpec.get()); |
| 1452 | } |
| 1453 | |
| 1454 | nsCOMPtr<nsIArray> redirects; |
| 1455 | rv = mQuery->GetRedirects(getter_AddRefs(redirects)); |
Value stored to 'rv' is never read | |
| 1456 | if (redirects) { |
| 1457 | AddRedirects(redirects); |
| 1458 | } else { |
| 1459 | LOG(("ApplicationReputation: Got no redirects [this=%p]", this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "ApplicationReputation: Got no redirects [this=%p]" , this); } } while (0); |
| 1460 | } |
| 1461 | |
| 1462 | rv = mQuery->GetSuggestedFileName(mFileName); |
| 1463 | if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !mFileName.IsEmpty()) { |
| 1464 | mIsBinaryFile = IsBinary(mFileName); |
| 1465 | LOG(("Suggested filename: %s [binary = %d, this = %p]", mFileName.get(),do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Suggested filename: %s [binary = %d, this = %p]" , mFileName.get(), mIsBinaryFile, this); } } while (0) |
| 1466 | mIsBinaryFile, this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Suggested filename: %s [binary = %d, this = %p]" , mFileName.get(), mIsBinaryFile, this); } } while (0); |
| 1467 | } else { |
| 1468 | nsAutoCString errorName; |
| 1469 | mozilla::GetErrorName(rv, errorName); |
| 1470 | LOG(("No suggested filename [rv = %s, this = %p]", errorName.get(), this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "No suggested filename [rv = %s, this = %p]" , errorName.get(), this); } } while (0); |
| 1471 | mFileName.Truncate(); |
| 1472 | } |
| 1473 | |
| 1474 | // We can skip parsing certificate for non-binary files because we only |
| 1475 | // check local block list for them. |
| 1476 | if (mIsBinaryFile) { |
| 1477 | nsTArray<nsTArray<nsTArray<uint8_t>>> sigArray; |
| 1478 | rv = mQuery->GetSignatureInfo(sigArray); |
| 1479 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1479); return rv; } } while (false); |
| 1480 | |
| 1481 | if (!sigArray.IsEmpty()) { |
| 1482 | rv = ParseCertificates(sigArray); |
| 1483 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1483); return rv; } } while (false); |
| 1484 | } |
| 1485 | |
| 1486 | rv = GenerateWhitelistStrings(); |
| 1487 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1487); return rv; } } while (false); |
| 1488 | } |
| 1489 | |
| 1490 | // Start the call chain. |
| 1491 | return LookupNext(); |
| 1492 | } |
| 1493 | |
| 1494 | nsresult PendingLookup::OnComplete(uint32_t aVerdict, Reason aReason, |
| 1495 | nsresult aRv) { |
| 1496 | if (NS_FAILED(aRv)((bool)(__builtin_expect(!!(NS_FAILED_impl(aRv)), 0)))) { |
| 1497 | nsAutoCString errorName; |
| 1498 | mozilla::GetErrorName(aRv, errorName); |
| 1499 | LOG(do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Failed sending remote query for application reputation " "[rv = %s, this = %p]", errorName.get(), this); } } while (0 ) |
| 1500 | ("Failed sending remote query for application reputation "do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Failed sending remote query for application reputation " "[rv = %s, this = %p]", errorName.get(), this); } } while (0 ) |
| 1501 | "[rv = %s, this = %p]",do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Failed sending remote query for application reputation " "[rv = %s, this = %p]", errorName.get(), this); } } while (0 ) |
| 1502 | errorName.get(), this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Failed sending remote query for application reputation " "[rv = %s, this = %p]", errorName.get(), this); } } while (0 ); |
| 1503 | } |
| 1504 | |
| 1505 | if (mTimeoutTimer) { |
| 1506 | mTimeoutTimer->Cancel(); |
| 1507 | mTimeoutTimer = nullptr; |
| 1508 | } |
| 1509 | |
| 1510 | bool shouldBlock = true; |
| 1511 | switch (aVerdict) { |
| 1512 | case nsIApplicationReputationService::VERDICT_DANGEROUS: |
| 1513 | if (!Preferences::GetBool(PREF_BLOCK_DANGEROUS"browser.safebrowsing.downloads.remote.block_dangerous", true)) { |
| 1514 | shouldBlock = false; |
| 1515 | aReason = Reason::eDangerousprefoff; |
| 1516 | } |
| 1517 | break; |
| 1518 | case nsIApplicationReputationService::VERDICT_UNCOMMON: |
| 1519 | if (!Preferences::GetBool(PREF_BLOCK_UNCOMMON"browser.safebrowsing.downloads.remote.block_uncommon", true)) { |
| 1520 | shouldBlock = false; |
| 1521 | aReason = Reason::eUncommonprefoff; |
| 1522 | } |
| 1523 | break; |
| 1524 | case nsIApplicationReputationService::VERDICT_POTENTIALLY_UNWANTED: |
| 1525 | if (!Preferences::GetBool(PREF_BLOCK_POTENTIALLY_UNWANTED"browser.safebrowsing.downloads.remote.block_potentially_unwanted", true)) { |
| 1526 | shouldBlock = false; |
| 1527 | aReason = Reason::eUnwantedprefoff; |
| 1528 | } |
| 1529 | break; |
| 1530 | case nsIApplicationReputationService::VERDICT_DANGEROUS_HOST: |
| 1531 | if (!Preferences::GetBool(PREF_BLOCK_DANGEROUS_HOST"browser.safebrowsing.downloads.remote.block_dangerous_host", true)) { |
| 1532 | shouldBlock = false; |
| 1533 | aReason = Reason::eDangeroushostprefoff; |
| 1534 | } |
| 1535 | break; |
| 1536 | default: |
| 1537 | shouldBlock = false; |
| 1538 | break; |
| 1539 | } |
| 1540 | |
| 1541 | mozilla::glean::application_reputation::reason.EnumGet(aReason).Add(); |
| 1542 | mozilla::glean::application_reputation::should_block |
| 1543 | .EnumGet( |
| 1544 | static_cast<mozilla::glean::application_reputation::ShouldBlockLabel>( |
| 1545 | shouldBlock)) |
| 1546 | .Add(); |
| 1547 | |
| 1548 | double t = (TimeStamp::Now() - mStartTime).ToMilliseconds(); |
| 1549 | LOG(("Application Reputation verdict is %u, obtained in %f ms [this = %p]",do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Application Reputation verdict is %u, obtained in %f ms [this = %p]" , aVerdict, t, this); } } while (0) |
| 1550 | aVerdict, t, this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Application Reputation verdict is %u, obtained in %f ms [this = %p]" , aVerdict, t, this); } } while (0); |
| 1551 | if (shouldBlock) { |
| 1552 | LOG(("Application Reputation check failed, blocking bad binary [this = %p]",do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Application Reputation check failed, blocking bad binary [this = %p]" , this); } } while (0) |
| 1553 | this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Application Reputation check failed, blocking bad binary [this = %p]" , this); } } while (0); |
| 1554 | } else { |
| 1555 | LOG(("Application Reputation check passed [this = %p]", this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Application Reputation check passed [this = %p]" , this); } } while (0); |
| 1556 | } |
| 1557 | |
| 1558 | nsresult res = mCallback->OnComplete(shouldBlock, aRv, aVerdict); |
| 1559 | return res; |
| 1560 | } |
| 1561 | |
| 1562 | nsresult PendingLookup::ParseCertificates( |
| 1563 | const nsTArray<nsTArray<nsTArray<uint8_t>>>& aSigArray) { |
| 1564 | // Binaries may be signed by multiple chains of certificates. If there are no |
| 1565 | // chains, the binary is unsigned (or we were unable to extract signature |
| 1566 | // information on a non-Windows platform) |
| 1567 | |
| 1568 | // Each chain may have multiple certificates. |
| 1569 | for (const auto& certList : aSigArray) { |
| 1570 | safe_browsing::ClientDownloadRequest_CertificateChain* certChain = |
| 1571 | mRequest.mutable_signature()->add_certificate_chain(); |
| 1572 | for (const auto& cert : certList) { |
| 1573 | // Add this certificate to the protobuf to send remotely. |
| 1574 | certChain->add_element()->set_certificate(cert.Elements(), cert.Length()); |
| 1575 | } |
| 1576 | } |
| 1577 | if (mRequest.signature().certificate_chain_size() > 0) { |
| 1578 | mRequest.mutable_signature()->set_trusted(true); |
| 1579 | } |
| 1580 | return NS_OK; |
| 1581 | } |
| 1582 | |
| 1583 | nsresult PendingLookup::SendRemoteQuery() { |
| 1584 | MOZ_ASSERT(!IsFileType(do { static_assert( mozilla::detail::AssertionConditionType< decltype(!IsFileType( mFileName, ApplicationReputationService ::kNonBinaryExecutables, std::size(ApplicationReputationService ::kNonBinaryExecutables)))>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(!IsFileType( mFileName, ApplicationReputationService ::kNonBinaryExecutables, std::size(ApplicationReputationService ::kNonBinaryExecutables))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure ("!IsFileType( mFileName, ApplicationReputationService::kNonBinaryExecutables, std::size(ApplicationReputationService::kNonBinaryExecutables))" , "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1586); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsFileType( mFileName, ApplicationReputationService::kNonBinaryExecutables, std::size(ApplicationReputationService::kNonBinaryExecutables))" ")"); do { MOZ_CrashSequence(__null, 1586); __attribute__((nomerge )) ::abort(); } while (false); } } while (false) |
| 1585 | mFileName, ApplicationReputationService::kNonBinaryExecutables,do { static_assert( mozilla::detail::AssertionConditionType< decltype(!IsFileType( mFileName, ApplicationReputationService ::kNonBinaryExecutables, std::size(ApplicationReputationService ::kNonBinaryExecutables)))>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(!IsFileType( mFileName, ApplicationReputationService ::kNonBinaryExecutables, std::size(ApplicationReputationService ::kNonBinaryExecutables))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure ("!IsFileType( mFileName, ApplicationReputationService::kNonBinaryExecutables, std::size(ApplicationReputationService::kNonBinaryExecutables))" , "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1586); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsFileType( mFileName, ApplicationReputationService::kNonBinaryExecutables, std::size(ApplicationReputationService::kNonBinaryExecutables))" ")"); do { MOZ_CrashSequence(__null, 1586); __attribute__((nomerge )) ::abort(); } while (false); } } while (false) |
| 1586 | std::size(ApplicationReputationService::kNonBinaryExecutables)))do { static_assert( mozilla::detail::AssertionConditionType< decltype(!IsFileType( mFileName, ApplicationReputationService ::kNonBinaryExecutables, std::size(ApplicationReputationService ::kNonBinaryExecutables)))>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(!IsFileType( mFileName, ApplicationReputationService ::kNonBinaryExecutables, std::size(ApplicationReputationService ::kNonBinaryExecutables))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure ("!IsFileType( mFileName, ApplicationReputationService::kNonBinaryExecutables, std::size(ApplicationReputationService::kNonBinaryExecutables))" , "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1586); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsFileType( mFileName, ApplicationReputationService::kNonBinaryExecutables, std::size(ApplicationReputationService::kNonBinaryExecutables))" ")"); do { MOZ_CrashSequence(__null, 1586); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
| 1587 | Reason reason = Reason::eNotset; |
| 1588 | nsresult rv = SendRemoteQueryInternal(reason); |
| 1589 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
| 1590 | return OnComplete(nsIApplicationReputationService::VERDICT_SAFE, reason, |
| 1591 | rv); |
| 1592 | } |
| 1593 | // SendRemoteQueryInternal has fired off the query and we call OnComplete in |
| 1594 | // the nsIStreamListener.onStopRequest. |
| 1595 | return rv; |
| 1596 | } |
| 1597 | |
| 1598 | nsresult PendingLookup::SendRemoteQueryInternal(Reason& aReason) { |
| 1599 | auto scopeExit = mozilla::MakeScopeExit([&aReason]() { |
| 1600 | if (aReason == Reason::eNotset) { |
| 1601 | aReason = Reason::eInternalerror; |
| 1602 | } |
| 1603 | }); |
| 1604 | |
| 1605 | // If we aren't supposed to do remote lookups, bail. |
| 1606 | if (!Preferences::GetBool(PREF_SB_DOWNLOADS_REMOTE_ENABLED"browser.safebrowsing.downloads.remote.enabled", false)) { |
| 1607 | LOG(("Remote lookups are disabled [this = %p]", this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Remote lookups are disabled [this = %p]" , this); } } while (0); |
| 1608 | aReason = Reason::eRemotelookupdisabled; |
| 1609 | return NS_ERROR_NOT_AVAILABLE; |
| 1610 | } |
| 1611 | // If the remote lookup URL is empty or absent, bail. |
| 1612 | nsString serviceUrl; |
| 1613 | nsCOMPtr<nsIURLFormatter> formatter( |
| 1614 | do_GetService("@mozilla.org/toolkit/URLFormatterService;1")); |
| 1615 | if (!formatter || |
| 1616 | NS_FAILED(formatter->FormatURLPref(((bool)(__builtin_expect(!!(NS_FAILED_impl(formatter->FormatURLPref ( NS_ConvertASCIItoUTF16("browser.safebrowsing.downloads.remote.url" ), serviceUrl))), 0))) |
| 1617 | NS_ConvertASCIItoUTF16(PREF_SB_APP_REP_URL), serviceUrl))((bool)(__builtin_expect(!!(NS_FAILED_impl(formatter->FormatURLPref ( NS_ConvertASCIItoUTF16("browser.safebrowsing.downloads.remote.url" ), serviceUrl))), 0))) || |
| 1618 | serviceUrl.IsEmpty() || u"about:blank"_ns.Equals(serviceUrl)) { |
| 1619 | LOG(("Remote lookup URL is empty or absent [this = %p]", this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Remote lookup URL is empty or absent [this = %p]" , this); } } while (0); |
| 1620 | aReason = Reason::eRemotelookupdisabled; |
| 1621 | return NS_ERROR_NOT_AVAILABLE; |
| 1622 | } |
| 1623 | |
| 1624 | LOG(("Sending remote query for application reputation [this = %p]", this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Sending remote query for application reputation [this = %p]" , this); } } while (0); |
| 1625 | // We did not find a local result, so fire off the query to the |
| 1626 | // application reputation service. |
| 1627 | nsCOMPtr<nsIURI> uri; |
| 1628 | nsresult rv; |
| 1629 | rv = mQuery->GetSourceURI(getter_AddRefs(uri)); |
| 1630 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1630); return rv; } } while (false); |
| 1631 | nsCString spec; |
| 1632 | rv = GetStrippedSpec(uri, spec); |
| 1633 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1633); return rv; } } while (false); |
| 1634 | mRequest.set_url(spec.get()); |
| 1635 | |
| 1636 | uint32_t fileSize; |
| 1637 | rv = mQuery->GetFileSize(&fileSize); |
| 1638 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1638); return rv; } } while (false); |
| 1639 | mRequest.set_length(fileSize); |
| 1640 | // We have no way of knowing whether or not a user initiated the |
| 1641 | // download. Set it to true to lessen the chance of false positives. |
| 1642 | mRequest.set_user_initiated(true); |
| 1643 | |
| 1644 | nsCString locale; |
| 1645 | rv = LocaleService::GetInstance()->GetAppLocaleAsBCP47(locale); |
| 1646 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1646); return rv; } } while (false); |
| 1647 | mRequest.set_locale(locale.get()); |
| 1648 | nsCString sha256Hash; |
| 1649 | rv = mQuery->GetSha256Hash(sha256Hash); |
| 1650 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1650); return rv; } } while (false); |
| 1651 | mRequest.mutable_digests()->set_sha256( |
| 1652 | std::string(sha256Hash.Data(), sha256Hash.Length())); |
| 1653 | mRequest.set_file_basename(mFileName.get()); |
| 1654 | mRequest.set_download_type(GetDownloadType(mFileName)); |
| 1655 | |
| 1656 | if (mRequest.signature().trusted()) { |
| 1657 | LOG(do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Got signed binary for remote application reputation check " "[this = %p]", this); } } while (0) |
| 1658 | ("Got signed binary for remote application reputation check "do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Got signed binary for remote application reputation check " "[this = %p]", this); } } while (0) |
| 1659 | "[this = %p]",do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Got signed binary for remote application reputation check " "[this = %p]", this); } } while (0) |
| 1660 | this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Got signed binary for remote application reputation check " "[this = %p]", this); } } while (0); |
| 1661 | } else { |
| 1662 | LOG(do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Got unsigned binary for remote application reputation check " "[this = %p]", this); } } while (0) |
| 1663 | ("Got unsigned binary for remote application reputation check "do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Got unsigned binary for remote application reputation check " "[this = %p]", this); } } while (0) |
| 1664 | "[this = %p]",do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Got unsigned binary for remote application reputation check " "[this = %p]", this); } } while (0) |
| 1665 | this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Got unsigned binary for remote application reputation check " "[this = %p]", this); } } while (0); |
| 1666 | } |
| 1667 | |
| 1668 | // Serialize the protocol buffer to a string. This can only fail if we are |
| 1669 | // out of memory, or if the protocol buffer req is missing required fields |
| 1670 | // (only the URL for now). |
| 1671 | std::string serialized; |
| 1672 | if (!mRequest.SerializeToString(&serialized)) { |
| 1673 | return NS_ERROR_UNEXPECTED; |
| 1674 | } |
| 1675 | |
| 1676 | if (LOG_ENABLED()(__builtin_expect(!!(mozilla::detail::log_test(ApplicationReputationService ::prlog, mozilla::LogLevel::Debug)), 0))) { |
| 1677 | nsAutoCString serializedStr(serialized.c_str(), serialized.length()); |
| 1678 | serializedStr.ReplaceSubstring("\0"_ns, "\\0"_ns); |
| 1679 | |
| 1680 | LOG(("Serialized protocol buffer [this = %p]: (length=%zd) %s", this,do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Serialized protocol buffer [this = %p]: (length=%zd) %s" , this, serializedStr.Length(), serializedStr.get()); } } while (0) |
| 1681 | serializedStr.Length(), serializedStr.get()))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Serialized protocol buffer [this = %p]: (length=%zd) %s" , this, serializedStr.Length(), serializedStr.get()); } } while (0); |
| 1682 | } |
| 1683 | |
| 1684 | // Set the input stream to the serialized protocol buffer |
| 1685 | nsCOMPtr<nsIStringInputStream> sstream = |
| 1686 | do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv); |
| 1687 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1687); return rv; } } while (false); |
| 1688 | |
| 1689 | rv = sstream->CopyData(serialized.c_str(), serialized.length()); |
| 1690 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1690); return rv; } } while (false); |
| 1691 | |
| 1692 | // Set up the channel to transmit the request to the service. |
| 1693 | nsCOMPtr<nsIIOService> ios = do_GetService(NS_IOSERVICE_CONTRACTID"@mozilla.org/network/io-service;1", &rv); |
| 1694 | rv = ios->NewChannel(NS_ConvertUTF16toUTF8(serviceUrl), nullptr, nullptr, |
| 1695 | nullptr, // aLoadingNode |
| 1696 | nsContentUtils::GetSystemPrincipal(), |
| 1697 | nullptr, // aTriggeringPrincipal |
| 1698 | nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL, |
| 1699 | nsIContentPolicy::TYPE_OTHER, getter_AddRefs(mChannel)); |
| 1700 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1700); return rv; } } while (false); |
| 1701 | |
| 1702 | mChannel->SetLoadFlags(nsIChannel::LOAD_BYPASS_URL_CLASSIFIER); |
| 1703 | |
| 1704 | nsCOMPtr<nsILoadInfo> loadInfo = mChannel->LoadInfo(); |
| 1705 | mozilla::OriginAttributes attrs; |
| 1706 | attrs.mFirstPartyDomain.AssignLiteral(NECKO_SAFEBROWSING_FIRST_PARTY_DOMAIN"safebrowsing.86868755-6b82-4842-b301-72671a0db32e.mozilla"); |
| 1707 | loadInfo->SetOriginAttributes(attrs); |
| 1708 | |
| 1709 | nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel, &rv)); |
| 1710 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1710); return rv; } } while (false); |
| 1711 | (void)httpChannel; |
| 1712 | |
| 1713 | // Upload the protobuf to the application reputation service. |
| 1714 | nsCOMPtr<nsIUploadChannel2> uploadChannel = do_QueryInterface(mChannel, &rv); |
| 1715 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1715); return rv; } } while (false); |
| 1716 | |
| 1717 | rv = uploadChannel->ExplicitSetUploadStream( |
| 1718 | sstream, "application/octet-stream"_ns, serialized.size(), "POST"_ns); |
| 1719 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1719); return rv; } } while (false); |
| 1720 | |
| 1721 | uint32_t timeoutMs = |
| 1722 | Preferences::GetUint(PREF_SB_DOWNLOADS_REMOTE_TIMEOUT"browser.safebrowsing.downloads.remote.timeout_ms", 10000); |
| 1723 | NS_NewTimerWithCallback(getter_AddRefs(mTimeoutTimer), this, timeoutMs, |
| 1724 | nsITimer::TYPE_ONE_SHOT); |
| 1725 | |
| 1726 | mTelemetryRemoteRequestStartMs = PR_IntervalNow(); |
| 1727 | |
| 1728 | rv = mChannel->AsyncOpen(this); |
| 1729 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1729); return rv; } } while (false); |
| 1730 | |
| 1731 | return NS_OK; |
| 1732 | } |
| 1733 | |
| 1734 | NS_IMETHODIMPnsresult |
| 1735 | PendingLookup::Notify(nsITimer* aTimer) { |
| 1736 | LOG(("Remote lookup timed out [this = %p]", this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Remote lookup timed out [this = %p]" , this); } } while (0); |
| 1737 | MOZ_ASSERT(aTimer == mTimeoutTimer)do { static_assert( mozilla::detail::AssertionConditionType< decltype(aTimer == mTimeoutTimer)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(aTimer == mTimeoutTimer))), 0 ))) { do { } while (false); MOZ_ReportAssertionFailure("aTimer == mTimeoutTimer" , "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1737); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aTimer == mTimeoutTimer" ")"); do { MOZ_CrashSequence(__null, 1737); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
| 1738 | mozilla::glean::application_reputation::remote_lookup_timeout |
| 1739 | .EnumGet(mozilla::glean::application_reputation:: |
| 1740 | RemoteLookupTimeoutLabel::eTrue) |
| 1741 | .Add(); |
| 1742 | mChannel->Cancel(NS_ERROR_NET_TIMEOUT_EXTERNAL); |
| 1743 | mTimeoutTimer->Cancel(); |
| 1744 | return NS_OK; |
| 1745 | } |
| 1746 | |
| 1747 | NS_IMETHODIMPnsresult |
| 1748 | PendingLookup::GetName(nsACString& aName) { |
| 1749 | aName.AssignLiteral("PendingLookup"); |
| 1750 | return NS_OK; |
| 1751 | } |
| 1752 | |
| 1753 | /////////////////////////////////////////////////////////////////////////////// |
| 1754 | // nsIObserver implementation |
| 1755 | NS_IMETHODIMPnsresult |
| 1756 | PendingLookup::Observe(nsISupports* aSubject, const char* aTopic, |
| 1757 | const char16_t* aData) { |
| 1758 | if (!strcmp(aTopic, "quit-application")) { |
| 1759 | if (mTimeoutTimer) { |
| 1760 | mTimeoutTimer->Cancel(); |
| 1761 | mTimeoutTimer = nullptr; |
| 1762 | } |
| 1763 | if (mChannel) { |
| 1764 | mChannel->Cancel(NS_ERROR_ABORT); |
| 1765 | } |
| 1766 | } |
| 1767 | return NS_OK; |
| 1768 | } |
| 1769 | |
| 1770 | //////////////////////////////////////////////////////////////////////////////// |
| 1771 | //// nsIStreamListener |
| 1772 | static nsresult AppendSegmentToString(nsIInputStream* inputStream, |
| 1773 | void* closure, const char* rawSegment, |
| 1774 | uint32_t toOffset, uint32_t count, |
| 1775 | uint32_t* writeCount) { |
| 1776 | nsAutoCString* decodedData = static_cast<nsAutoCString*>(closure); |
| 1777 | decodedData->Append(rawSegment, count); |
| 1778 | *writeCount = count; |
| 1779 | return NS_OK; |
| 1780 | } |
| 1781 | |
| 1782 | NS_IMETHODIMPnsresult |
| 1783 | PendingLookup::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aStream, |
| 1784 | uint64_t offset, uint32_t count) { |
| 1785 | uint32_t read; |
| 1786 | return aStream->ReadSegments(AppendSegmentToString, &mResponse, count, &read); |
| 1787 | } |
| 1788 | |
| 1789 | NS_IMETHODIMPnsresult |
| 1790 | PendingLookup::OnStartRequest(nsIRequest* aRequest) { return NS_OK; } |
| 1791 | |
| 1792 | NS_IMETHODIMPnsresult |
| 1793 | PendingLookup::OnStopRequest(nsIRequest* aRequest, nsresult aResult) { |
| 1794 | NS_ENSURE_STATE(mCallback)do { if ((__builtin_expect(!!(!(mCallback)), 0))) { NS_DebugBreak (NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mCallback" ") failed", nullptr , "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1794); return NS_ERROR_UNEXPECTED; } } while (false); |
| 1795 | |
| 1796 | if (aResult != NS_ERROR_NET_TIMEOUT_EXTERNAL) { |
| 1797 | mozilla::glean::application_reputation::remote_lookup_timeout |
| 1798 | .EnumGet(mozilla::glean::application_reputation:: |
| 1799 | RemoteLookupTimeoutLabel::eFalse) |
| 1800 | .Add(); |
| 1801 | |
| 1802 | MOZ_ASSERT(mTelemetryRemoteRequestStartMs > 0)do { static_assert( mozilla::detail::AssertionConditionType< decltype(mTelemetryRemoteRequestStartMs > 0)>::isValid, "invalid assertion condition"); if ((__builtin_expect(!!(!(! !(mTelemetryRemoteRequestStartMs > 0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("mTelemetryRemoteRequestStartMs > 0" , "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1802); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mTelemetryRemoteRequestStartMs > 0" ")"); do { MOZ_CrashSequence(__null, 1802); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
| 1803 | int32_t msecs = PR_IntervalToMilliseconds(PR_IntervalNow() - |
| 1804 | mTelemetryRemoteRequestStartMs); |
| 1805 | |
| 1806 | MOZ_ASSERT(msecs >= 0)do { static_assert( mozilla::detail::AssertionConditionType< decltype(msecs >= 0)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(msecs >= 0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("msecs >= 0", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1806); AnnotateMozCrashReason("MOZ_ASSERT" "(" "msecs >= 0" ")"); do { MOZ_CrashSequence(__null, 1806); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
| 1807 | mozilla::glean::application_reputation::remote_lookup_response_time |
| 1808 | .AccumulateRawDuration(mozilla::TimeDuration::FromMilliseconds(msecs)); |
| 1809 | } |
| 1810 | |
| 1811 | uint32_t verdict = nsIApplicationReputationService::VERDICT_SAFE; |
| 1812 | Reason reason = Reason::eNotset; |
| 1813 | nsresult rv = OnStopRequestInternal(aRequest, aResult, verdict, reason); |
| 1814 | OnComplete(verdict, reason, rv); |
| 1815 | return rv; |
| 1816 | } |
| 1817 | |
| 1818 | nsresult PendingLookup::OnStopRequestInternal(nsIRequest* aRequest, |
| 1819 | nsresult aResult, |
| 1820 | uint32_t& aVerdict, |
| 1821 | Reason& aReason) { |
| 1822 | auto scopeExit = mozilla::MakeScopeExit([&aReason]() { |
| 1823 | // If |aReason| is not set while exiting, there must be an error. |
| 1824 | if (aReason == Reason::eNotset) { |
| 1825 | aReason = Reason::eNetworkerror; |
| 1826 | } |
| 1827 | }); |
| 1828 | |
| 1829 | if (NS_FAILED(aResult)((bool)(__builtin_expect(!!(NS_FAILED_impl(aResult)), 0)))) { |
| 1830 | mozilla::glean::application_reputation::server.AccumulateSingleSample( |
| 1831 | SERVER_RESPONSE_FAILED); |
| 1832 | mozilla::glean::application_reputation::server_2 |
| 1833 | .EnumGet(NSErrorToLabel(aResult)) |
| 1834 | .Add(); |
| 1835 | return aResult; |
| 1836 | } |
| 1837 | |
| 1838 | nsresult rv; |
| 1839 | nsCOMPtr<nsIHttpChannel> channel = do_QueryInterface(aRequest, &rv); |
| 1840 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
| 1841 | mozilla::glean::application_reputation::server.AccumulateSingleSample( |
| 1842 | SERVER_RESPONSE_FAILED); |
| 1843 | mozilla::glean::application_reputation::server_2 |
| 1844 | .EnumGet(mozilla::glean::application_reputation::Server2Label:: |
| 1845 | eFailgetchannel) |
| 1846 | .Add(); |
| 1847 | return rv; |
| 1848 | } |
| 1849 | |
| 1850 | uint32_t status = 0; |
| 1851 | rv = channel->GetResponseStatus(&status); |
| 1852 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
| 1853 | mozilla::glean::application_reputation::server.AccumulateSingleSample( |
| 1854 | SERVER_RESPONSE_FAILED); |
| 1855 | mozilla::glean::application_reputation::server_2 |
| 1856 | .EnumGet(mozilla::glean::application_reputation::Server2Label:: |
| 1857 | eFailgetresponse) |
| 1858 | .Add(); |
| 1859 | return rv; |
| 1860 | } |
| 1861 | |
| 1862 | if (status != 200) { |
| 1863 | mozilla::glean::application_reputation::server.AccumulateSingleSample( |
| 1864 | SERVER_RESPONSE_FAILED); |
| 1865 | mozilla::glean::application_reputation::server_2 |
| 1866 | .EnumGet(HTTPStatusToLabel(status)) |
| 1867 | .Add(); |
| 1868 | return NS_ERROR_NOT_AVAILABLE; |
| 1869 | } |
| 1870 | |
| 1871 | std::string buf(mResponse.Data(), mResponse.Length()); |
| 1872 | safe_browsing::ClientDownloadResponse response; |
| 1873 | if (!response.ParseFromString(buf)) { |
| 1874 | LOG(("Invalid protocol buffer response [this = %p]: %s", this,do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Invalid protocol buffer response [this = %p]: %s" , this, buf.c_str()); } } while (0) |
| 1875 | buf.c_str()))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Invalid protocol buffer response [this = %p]: %s" , this, buf.c_str()); } } while (0); |
| 1876 | mozilla::glean::application_reputation::server.AccumulateSingleSample( |
| 1877 | SERVER_RESPONSE_INVALID); |
| 1878 | return NS_ERROR_CANNOT_CONVERT_DATA; |
| 1879 | } |
| 1880 | |
| 1881 | mozilla::glean::application_reputation::server.AccumulateSingleSample( |
| 1882 | SERVER_RESPONSE_VALID); |
| 1883 | mozilla::glean::application_reputation::server_2 |
| 1884 | .EnumGet( |
| 1885 | mozilla::glean::application_reputation::Server2Label::eResponsevalid) |
| 1886 | .Add(); |
| 1887 | |
| 1888 | // Clamp responses 0-7, we only know about 0-4 for now. |
| 1889 | mozilla::glean::application_reputation::server_verdict.AccumulateSingleSample( |
| 1890 | std::min<uint32_t>(response.verdict(), 7)); |
| 1891 | const char* ext = GetFileExt(mFileName); |
| 1892 | mozilla::glean::application_reputation::server_verdict_2.Get( |
| 1893 | nsCString(ext), |
| 1894 | VerdictToLabel(std::min<uint32_t>(response.verdict(), 7))); |
| 1895 | switch (response.verdict()) { |
| 1896 | case safe_browsing::ClientDownloadResponse::DANGEROUS: |
| 1897 | aVerdict = nsIApplicationReputationService::VERDICT_DANGEROUS; |
| 1898 | aReason = Reason::eVerdictdangerous; |
| 1899 | break; |
| 1900 | case safe_browsing::ClientDownloadResponse::DANGEROUS_HOST: |
| 1901 | aVerdict = nsIApplicationReputationService::VERDICT_DANGEROUS_HOST; |
| 1902 | aReason = Reason::eVerdictdangeroushost; |
| 1903 | break; |
| 1904 | case safe_browsing::ClientDownloadResponse::POTENTIALLY_UNWANTED: |
| 1905 | aVerdict = nsIApplicationReputationService::VERDICT_POTENTIALLY_UNWANTED; |
| 1906 | aReason = Reason::eVerdictunwanted; |
| 1907 | break; |
| 1908 | case safe_browsing::ClientDownloadResponse::UNCOMMON: |
| 1909 | aVerdict = nsIApplicationReputationService::VERDICT_UNCOMMON; |
| 1910 | aReason = Reason::eVerdictuncommon; |
| 1911 | break; |
| 1912 | case safe_browsing::ClientDownloadResponse::UNKNOWN: |
| 1913 | aVerdict = nsIApplicationReputationService::VERDICT_SAFE; |
| 1914 | aReason = Reason::eVerdictunknown; |
| 1915 | break; |
| 1916 | case safe_browsing::ClientDownloadResponse::SAFE: |
| 1917 | aVerdict = nsIApplicationReputationService::VERDICT_SAFE; |
| 1918 | aReason = Reason::eVerdictsafe; |
| 1919 | break; |
| 1920 | default: |
| 1921 | // Treat everything else as safe |
| 1922 | aVerdict = nsIApplicationReputationService::VERDICT_SAFE; |
| 1923 | aReason = Reason::eVerdictunrecognized; |
| 1924 | break; |
| 1925 | } |
| 1926 | |
| 1927 | return NS_OK; |
| 1928 | } |
| 1929 | |
| 1930 | NS_IMPL_ISUPPORTS(ApplicationReputationService, nsIApplicationReputationService)MozExternalRefCountType ApplicationReputationService::AddRef( void) { static_assert(!std::is_destructible_v<ApplicationReputationService >, "Reference-counted class " "ApplicationReputationService" " should not have a public destructor. " "Make this class's destructor non-public" ); do { static_assert( mozilla::detail::AssertionConditionType <decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0" " (" "illegal refcnt" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1930); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0" ") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 1930 ); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); do { static_assert( mozilla::detail::AssertionConditionType <decltype("ApplicationReputationService" != nullptr)>:: isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!("ApplicationReputationService" != nullptr))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"ApplicationReputationService\" != nullptr" " (" "Must specify a name" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1930); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"ApplicationReputationService\" != nullptr" ") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null , 1930); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread .AssertOwnership("ApplicationReputationService" " not thread-safe" ); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), ( "ApplicationReputationService"), (uint32_t)(sizeof(*this))); return count; } MozExternalRefCountType ApplicationReputationService ::Release(void) { do { static_assert( mozilla::detail::AssertionConditionType <decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0 ))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0" " (" "dup release" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1930); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0" ") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 1930 ); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); do { static_assert( mozilla::detail::AssertionConditionType <decltype("ApplicationReputationService" != nullptr)>:: isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!("ApplicationReputationService" != nullptr))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"ApplicationReputationService\" != nullptr" " (" "Must specify a name" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1930); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"ApplicationReputationService\" != nullptr" ") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null , 1930); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread .AssertOwnership("ApplicationReputationService" " not thread-safe" ); const char* const nametmp = "ApplicationReputationService" ; nsrefcnt count = --mRefCnt; NS_LogRelease((this), (count), ( nametmp)); if (count == 0) { mRefCnt = 1; delete (this); return 0; } return count; } nsresult ApplicationReputationService:: QueryInterface(const nsIID& aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!" , "aInstancePtr", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1930); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE ; static_assert(1 > 0, "Need more arguments to NS_INTERFACE_TABLE" ); static const QITableEntry table[] = { {&mozilla::detail ::kImplementedIID<ApplicationReputationService, nsIApplicationReputationService >, int32_t( reinterpret_cast<char*>(static_cast<nsIApplicationReputationService *>((ApplicationReputationService*)0x1000)) - reinterpret_cast <char*>((ApplicationReputationService*)0x1000))}, {& mozilla::detail::kImplementedIID<ApplicationReputationService , nsISupports>, int32_t(reinterpret_cast<char*>(static_cast <nsISupports*>( static_cast<nsIApplicationReputationService *>((ApplicationReputationService*)0x1000))) - reinterpret_cast <char*>((ApplicationReputationService*)0x1000))}, { nullptr , 0 } } ; static_assert(std::size(table) > 1, "need at least 1 interface" ); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID , aInstancePtr, table); return rv; } |
| 1931 | |
| 1932 | ApplicationReputationService* |
| 1933 | ApplicationReputationService::gApplicationReputationService = nullptr; |
| 1934 | |
| 1935 | already_AddRefed<ApplicationReputationService> |
| 1936 | ApplicationReputationService::GetSingleton() { |
| 1937 | if (!gApplicationReputationService) { |
| 1938 | // Note: This is cleared in the new ApplicationReputationService destructor. |
| 1939 | gApplicationReputationService = new ApplicationReputationService(); |
| 1940 | } |
| 1941 | return do_AddRef(gApplicationReputationService); |
| 1942 | } |
| 1943 | |
| 1944 | ApplicationReputationService::ApplicationReputationService() { |
| 1945 | LOG(("Application reputation service started up"))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Application reputation service started up" ); } } while (0); |
| 1946 | } |
| 1947 | |
| 1948 | ApplicationReputationService::~ApplicationReputationService() { |
| 1949 | LOG(("Application reputation service shutting down"))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Application reputation service shutting down" ); } } while (0); |
| 1950 | MOZ_ASSERT(gApplicationReputationService == this)do { static_assert( mozilla::detail::AssertionConditionType< decltype(gApplicationReputationService == this)>::isValid, "invalid assertion condition"); if ((__builtin_expect(!!(!(! !(gApplicationReputationService == this))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("gApplicationReputationService == this" , "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1950); AnnotateMozCrashReason("MOZ_ASSERT" "(" "gApplicationReputationService == this" ")"); do { MOZ_CrashSequence(__null, 1950); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
| 1951 | gApplicationReputationService = nullptr; |
| 1952 | } |
| 1953 | |
| 1954 | NS_IMETHODIMPnsresult |
| 1955 | ApplicationReputationService::QueryReputation( |
| 1956 | nsIApplicationReputationQuery* aQuery, |
| 1957 | nsIApplicationReputationCallback* aCallback) { |
| 1958 | LOG(("Starting application reputation check [query=%p]", aQuery))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Starting application reputation check [query=%p]" , aQuery); } } while (0); |
| 1959 | NS_ENSURE_ARG_POINTER(aQuery)do { if ((__builtin_expect(!!(!(aQuery)), 0))) { NS_DebugBreak (NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aQuery" ") failed", nullptr , "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1959); return NS_ERROR_INVALID_POINTER; } } while (false); |
| 1960 | NS_ENSURE_ARG_POINTER(aCallback)do { if ((__builtin_expect(!!(!(aCallback)), 0))) { NS_DebugBreak (NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aCallback" ") failed", nullptr , "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1960); return NS_ERROR_INVALID_POINTER; } } while (false); |
| 1961 | |
| 1962 | nsresult rv = QueryReputationInternal(aQuery, aCallback); |
| 1963 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
| 1964 | Reason reason = rv == NS_ERROR_NOT_AVAILABLE ? Reason::eDpdisabled |
| 1965 | : Reason::eInternalerror; |
| 1966 | |
| 1967 | mozilla::glean::application_reputation::reason.EnumGet(reason).Add(); |
| 1968 | mozilla::glean::application_reputation::should_block |
| 1969 | .EnumGet( |
| 1970 | mozilla::glean::application_reputation::ShouldBlockLabel::eFalse) |
| 1971 | .Add(); |
| 1972 | |
| 1973 | aCallback->OnComplete(false, rv, |
| 1974 | nsIApplicationReputationService::VERDICT_SAFE); |
| 1975 | } |
| 1976 | return NS_OK; |
| 1977 | } |
| 1978 | |
| 1979 | nsresult ApplicationReputationService::QueryReputationInternal( |
| 1980 | nsIApplicationReputationQuery* aQuery, |
| 1981 | nsIApplicationReputationCallback* aCallback) { |
| 1982 | // If malware checks aren't enabled, don't query application reputation. |
| 1983 | if (!Preferences::GetBool(PREF_SB_MALWARE_ENABLED"browser.safebrowsing.malware.enabled", false)) { |
| 1984 | return NS_ERROR_NOT_AVAILABLE; |
| 1985 | } |
| 1986 | |
| 1987 | if (!Preferences::GetBool(PREF_SB_DOWNLOADS_ENABLED"browser.safebrowsing.downloads.enabled", false)) { |
| 1988 | return NS_ERROR_NOT_AVAILABLE; |
| 1989 | } |
| 1990 | |
| 1991 | nsCOMPtr<nsIURI> uri; |
| 1992 | nsresult rv = aQuery->GetSourceURI(getter_AddRefs(uri)); |
| 1993 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1993); return rv; } } while (false); |
| 1994 | // Bail if the URI hasn't been set. |
| 1995 | NS_ENSURE_STATE(uri)do { if ((__builtin_expect(!!(!(uri)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING , "NS_ENSURE_TRUE(" "uri" ") failed", nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp" , 1995); return NS_ERROR_UNEXPECTED; } } while (false); |
| 1996 | |
| 1997 | // Create a new pending lookup and start the call chain. |
| 1998 | RefPtr<PendingLookup> lookup(new PendingLookup(aQuery, aCallback)); |
| 1999 | |
| 2000 | // Add an observer for shutdown |
| 2001 | nsCOMPtr<nsIObserverService> observerService = |
| 2002 | mozilla::services::GetObserverService(); |
| 2003 | if (!observerService) { |
| 2004 | return NS_ERROR_FAILURE; |
| 2005 | } |
| 2006 | |
| 2007 | observerService->AddObserver(lookup, "quit-application", true); |
| 2008 | return lookup->StartLookup(); |
| 2009 | } |
| 2010 | |
| 2011 | nsresult ApplicationReputationService::IsBinary(const nsACString& aFileName, |
| 2012 | bool* aBinary) { |
| 2013 | *aBinary = ::IsBinary(aFileName); |
| 2014 | return NS_OK; |
| 2015 | } |
| 2016 | |
| 2017 | nsresult ApplicationReputationService::IsExecutable(const nsACString& aFileName, |
| 2018 | bool* aExecutable) { |
| 2019 | *aExecutable = |
| 2020 | ::IsFileType(aFileName, sExecutableExts, std::size(sExecutableExts)); |
| 2021 | return NS_OK; |
| 2022 | } |