Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(542)

Side by Side Diff: chrome/browser/extensions/sandboxed_extension_unpacker.cc

Issue 8890086: Issue 71980: Extensions code should use UTF-16 for user-visible Unicode strings (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/sandboxed_extension_unpacker.h" 5 #include "chrome/browser/extensions/sandboxed_extension_unpacker.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/base64.h" 9 #include "base/base64.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 location_(location), creation_flags_(creation_flags) { 122 location_(location), creation_flags_(creation_flags) {
123 } 123 }
124 124
125 bool SandboxedExtensionUnpacker::CreateTempDirectory() { 125 bool SandboxedExtensionUnpacker::CreateTempDirectory() {
126 CHECK(BrowserThread::GetCurrentThreadIdentifier(&thread_identifier_)); 126 CHECK(BrowserThread::GetCurrentThreadIdentifier(&thread_identifier_));
127 127
128 FilePath user_data_temp_dir = extension_file_util::GetUserDataTempDir(); 128 FilePath user_data_temp_dir = extension_file_util::GetUserDataTempDir();
129 if (user_data_temp_dir.empty()) { 129 if (user_data_temp_dir.empty()) {
130 ReportFailure( 130 ReportFailure(
131 COULD_NOT_GET_TEMP_DIRECTORY, 131 COULD_NOT_GET_TEMP_DIRECTORY,
132 l10n_util::GetStringFUTF8( 132 l10n_util::GetStringFUTF16(
133 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 133 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
134 ASCIIToUTF16("COULD_NOT_GET_TEMP_DIRECTORY"))); 134 ASCIIToUTF16("COULD_NOT_GET_TEMP_DIRECTORY")));
135 return false; 135 return false;
136 } 136 }
137 137
138 if (!temp_dir_.CreateUniqueTempDirUnderPath(user_data_temp_dir)) { 138 if (!temp_dir_.CreateUniqueTempDirUnderPath(user_data_temp_dir)) {
139 ReportFailure( 139 ReportFailure(
140 COULD_NOT_CREATE_TEMP_DIRECTORY, 140 COULD_NOT_CREATE_TEMP_DIRECTORY,
141 l10n_util::GetStringFUTF8( 141 l10n_util::GetStringFUTF16(
142 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 142 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
143 ASCIIToUTF16("COULD_NOT_CREATE_TEMP_DIRECTORY"))); 143 ASCIIToUTF16("COULD_NOT_CREATE_TEMP_DIRECTORY")));
144 return false; 144 return false;
145 } 145 }
146 146
147 return true; 147 return true;
148 } 148 }
149 149
150 void SandboxedExtensionUnpacker::Start() { 150 void SandboxedExtensionUnpacker::Start() {
151 // We assume that we are started on the thread that the client wants us to do 151 // We assume that we are started on the thread that the client wants us to do
(...skipping 19 matching lines...) Expand all
171 171
172 // Copy the crx file into our working directory. 172 // Copy the crx file into our working directory.
173 FilePath temp_crx_path = temp_dir_.path().Append(crx_path_.BaseName()); 173 FilePath temp_crx_path = temp_dir_.path().Append(crx_path_.BaseName());
174 PATH_LENGTH_HISTOGRAM("Extensions.SandboxUnpackTempCrxPathLength", 174 PATH_LENGTH_HISTOGRAM("Extensions.SandboxUnpackTempCrxPathLength",
175 temp_crx_path); 175 temp_crx_path);
176 176
177 if (!file_util::CopyFile(crx_path_, temp_crx_path)) { 177 if (!file_util::CopyFile(crx_path_, temp_crx_path)) {
178 // Failed to copy extension file to temporary directory. 178 // Failed to copy extension file to temporary directory.
179 ReportFailure( 179 ReportFailure(
180 FAILED_TO_COPY_EXTENSION_FILE_TO_TEMP_DIRECTORY, 180 FAILED_TO_COPY_EXTENSION_FILE_TO_TEMP_DIRECTORY,
181 l10n_util::GetStringFUTF8( 181 l10n_util::GetStringFUTF16(
182 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 182 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
183 ASCIIToUTF16("FAILED_TO_COPY_EXTENSION_FILE_TO_TEMP_DIRECTORY"))); 183 ASCIIToUTF16("FAILED_TO_COPY_EXTENSION_FILE_TO_TEMP_DIRECTORY")));
184 return; 184 return;
185 } 185 }
186 186
187 // If we are supposed to use a subprocess, kick off the subprocess. 187 // If we are supposed to use a subprocess, kick off the subprocess.
188 // 188 //
189 // TODO(asargent) we shouldn't need to do this branch here - instead 189 // TODO(asargent) we shouldn't need to do this branch here - instead
190 // UtilityProcessHost should handle it for us. (http://crbug.com/19192) 190 // UtilityProcessHost should handle it for us. (http://crbug.com/19192)
191 bool use_utility_process = rdh_ && 191 bool use_utility_process = rdh_ &&
192 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess); 192 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess);
193 if (use_utility_process) { 193 if (use_utility_process) {
194 // The utility process will have access to the directory passed to 194 // The utility process will have access to the directory passed to
195 // SandboxedExtensionUnpacker. That directory should not contain a 195 // SandboxedExtensionUnpacker. That directory should not contain a
196 // symlink or NTFS reparse point. When the path is used, following 196 // symlink or NTFS reparse point. When the path is used, following
197 // the link/reparse point will cause file system access outside the 197 // the link/reparse point will cause file system access outside the
198 // sandbox path, and the sandbox will deny the operation. 198 // sandbox path, and the sandbox will deny the operation.
199 FilePath link_free_crx_path; 199 FilePath link_free_crx_path;
200 if (!file_util::NormalizeFilePath(temp_crx_path, &link_free_crx_path)) { 200 if (!file_util::NormalizeFilePath(temp_crx_path, &link_free_crx_path)) {
201 LOG(ERROR) << "Could not get the normalized path of " 201 LOG(ERROR) << "Could not get the normalized path of "
202 << temp_crx_path.value(); 202 << temp_crx_path.value();
203 ReportFailure( 203 ReportFailure(
204 COULD_NOT_GET_SANDBOX_FRIENDLY_PATH, 204 COULD_NOT_GET_SANDBOX_FRIENDLY_PATH,
205 l10n_util::GetStringUTF8(IDS_EXTENSION_UNPACK_FAILED)); 205 l10n_util::GetStringUTF16(IDS_EXTENSION_UNPACK_FAILED));
206 return; 206 return;
207 } 207 }
208 PATH_LENGTH_HISTOGRAM("Extensions.SandboxUnpackLinkFreeCrxPathLength", 208 PATH_LENGTH_HISTOGRAM("Extensions.SandboxUnpackLinkFreeCrxPathLength",
209 link_free_crx_path); 209 link_free_crx_path);
210 210
211 BrowserThread::PostTask( 211 BrowserThread::PostTask(
212 BrowserThread::IO, FROM_HERE, 212 BrowserThread::IO, FROM_HERE,
213 base::Bind( 213 base::Bind(
214 &SandboxedExtensionUnpacker::StartProcessOnIOThread, 214 &SandboxedExtensionUnpacker::StartProcessOnIOThread,
215 this, 215 this,
(...skipping 30 matching lines...) Expand all
246 } 246 }
247 247
248 void SandboxedExtensionUnpacker::OnProcessCrashed(int exit_code) { 248 void SandboxedExtensionUnpacker::OnProcessCrashed(int exit_code) {
249 // Don't report crashes if they happen after we got a response. 249 // Don't report crashes if they happen after we got a response.
250 if (got_response_) 250 if (got_response_)
251 return; 251 return;
252 252
253 // Utility process crashed while trying to install. 253 // Utility process crashed while trying to install.
254 ReportFailure( 254 ReportFailure(
255 UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL, 255 UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL,
256 l10n_util::GetStringFUTF8( 256 l10n_util::GetStringFUTF16(
257 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 257 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
258 ASCIIToUTF16("UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL"))); 258 ASCIIToUTF16("UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL")));
259 } 259 }
260 260
261 void SandboxedExtensionUnpacker::StartProcessOnIOThread( 261 void SandboxedExtensionUnpacker::StartProcessOnIOThread(
262 const FilePath& temp_crx_path) { 262 const FilePath& temp_crx_path) {
263 UtilityProcessHost* host = new UtilityProcessHost(this, thread_identifier_); 263 UtilityProcessHost* host = new UtilityProcessHost(this, thread_identifier_);
264 // Grant the subprocess access to the entire subdir the extension file is 264 // Grant the subprocess access to the entire subdir the extension file is
265 // in, so that it can unpack to that dir. 265 // in, so that it can unpack to that dir.
266 host->set_exposed_dir(temp_crx_path.DirName()); 266 host->set_exposed_dir(temp_crx_path.DirName());
(...skipping 12 matching lines...) Expand all
279 scoped_ptr<DictionaryValue> final_manifest(RewriteManifestFile(manifest)); 279 scoped_ptr<DictionaryValue> final_manifest(RewriteManifestFile(manifest));
280 if (!final_manifest.get()) 280 if (!final_manifest.get())
281 return; 281 return;
282 282
283 // Create an extension object that refers to the temporary location the 283 // Create an extension object that refers to the temporary location the
284 // extension was unpacked to. We use this until the extension is finally 284 // extension was unpacked to. We use this until the extension is finally
285 // installed. For example, the install UI shows images from inside the 285 // installed. For example, the install UI shows images from inside the
286 // extension. 286 // extension.
287 287
288 // Localize manifest now, so confirm UI gets correct extension name. 288 // Localize manifest now, so confirm UI gets correct extension name.
289 std::string error; 289
290 // TODO(rdevlin.cronin): Continue removing std::string errors and replacing
291 // with string16
292 std::string utf8_error;
290 if (!extension_l10n_util::LocalizeExtension(extension_root_, 293 if (!extension_l10n_util::LocalizeExtension(extension_root_,
291 final_manifest.get(), 294 final_manifest.get(),
292 &error)) { 295 &utf8_error)) {
293 ReportFailure( 296 ReportFailure(
294 COULD_NOT_LOCALIZE_EXTENSION, 297 COULD_NOT_LOCALIZE_EXTENSION,
295 l10n_util::GetStringFUTF8( 298 l10n_util::GetStringFUTF16(
296 IDS_EXTENSION_PACKAGE_ERROR_MESSAGE, 299 IDS_EXTENSION_PACKAGE_ERROR_MESSAGE,
297 ASCIIToUTF16(error))); 300 UTF8ToUTF16(utf8_error)));
298 return; 301 return;
299 } 302 }
300 303
301 extension_ = Extension::Create( 304 extension_ = Extension::Create(
302 extension_root_, 305 extension_root_,
303 location_, 306 location_,
304 *final_manifest, 307 *final_manifest,
305 Extension::REQUIRE_KEY | creation_flags_, 308 Extension::REQUIRE_KEY | creation_flags_,
306 &error); 309 &utf8_error);
310
307 311
308 if (!extension_.get()) { 312 if (!extension_.get()) {
309 ReportFailure( 313 ReportFailure(
310 INVALID_MANIFEST, 314 INVALID_MANIFEST,
311 std::string("Manifest is invalid: ") + error); 315 ASCIIToUTF16("Manifest is invalid: " + utf8_error));
312 return; 316 return;
313 } 317 }
314 318
315 if (!RewriteImageFiles()) 319 if (!RewriteImageFiles())
316 return; 320 return;
317 321
318 if (!RewriteCatalogFiles()) 322 if (!RewriteCatalogFiles())
319 return; 323 return;
320 324
321 ReportSuccess(manifest); 325 ReportSuccess(manifest);
322 } 326 }
323 327
324 void SandboxedExtensionUnpacker::OnUnpackExtensionFailed( 328 void SandboxedExtensionUnpacker::OnUnpackExtensionFailed(
325 const std::string& error) { 329 const string16& error) {
326 CHECK(BrowserThread::CurrentlyOn(thread_identifier_)); 330 CHECK(BrowserThread::CurrentlyOn(thread_identifier_));
327 got_response_ = true; 331 got_response_ = true;
328 ReportFailure( 332 ReportFailure(
329 UNPACKER_CLIENT_FAILED, 333 UNPACKER_CLIENT_FAILED,
330 l10n_util::GetStringFUTF8( 334 l10n_util::GetStringFUTF16(
331 IDS_EXTENSION_PACKAGE_ERROR_MESSAGE, 335 IDS_EXTENSION_PACKAGE_ERROR_MESSAGE,
332 ASCIIToUTF16(error))); 336 error));
333 } 337 }
334 338
335 bool SandboxedExtensionUnpacker::ValidateSignature() { 339 bool SandboxedExtensionUnpacker::ValidateSignature() {
336 ScopedStdioHandle file(file_util::OpenFile(crx_path_, "rb")); 340 ScopedStdioHandle file(file_util::OpenFile(crx_path_, "rb"));
337 341
338 if (!file.get()) { 342 if (!file.get()) {
339 // Could not open crx file for reading. 343 // Could not open crx file for reading.
340 #if defined (OS_WIN) 344 #if defined (OS_WIN)
341 // On windows, get the error code. 345 // On windows, get the error code.
342 uint32 error_code = ::GetLastError(); 346 uint32 error_code = ::GetLastError();
343 // TODO(skerner): Use this histogram to understand why so many 347 // TODO(skerner): Use this histogram to understand why so many
344 // windows users hit this error. crbug.com/69693 348 // windows users hit this error. crbug.com/69693
345 349
346 // Windows errors are unit32s, but all of likely errors are in 350 // Windows errors are unit32s, but all of likely errors are in
347 // [1, 1000]. See winerror.h for the meaning of specific values. 351 // [1, 1000]. See winerror.h for the meaning of specific values.
348 // Clip errors outside the expected range to a single extra value. 352 // Clip errors outside the expected range to a single extra value.
349 // If there are errors in that extra bucket, we will know to expand 353 // If there are errors in that extra bucket, we will know to expand
350 // the range. 354 // the range.
351 const uint32 kMaxErrorToSend = 1001; 355 const uint32 kMaxErrorToSend = 1001;
352 error_code = std::min(error_code, kMaxErrorToSend); 356 error_code = std::min(error_code, kMaxErrorToSend);
353 UMA_HISTOGRAM_ENUMERATION("Extensions.ErrorCodeFromCrxOpen", 357 UMA_HISTOGRAM_ENUMERATION("Extensions.ErrorCodeFromCrxOpen",
354 error_code, kMaxErrorToSend); 358 error_code, kMaxErrorToSend);
355 #endif 359 #endif
356 360
357 ReportFailure( 361 ReportFailure(
358 CRX_FILE_NOT_READABLE, 362 CRX_FILE_NOT_READABLE,
359 l10n_util::GetStringFUTF8( 363 l10n_util::GetStringFUTF16(
360 IDS_EXTENSION_PACKAGE_ERROR_CODE, 364 IDS_EXTENSION_PACKAGE_ERROR_CODE,
361 ASCIIToUTF16("CRX_FILE_NOT_READABLE"))); 365 ASCIIToUTF16("CRX_FILE_NOT_READABLE")));
362 return false; 366 return false;
363 } 367 }
364 368
365 // Read and verify the header. 369 // Read and verify the header.
366 ExtensionHeader header; 370 ExtensionHeader header;
367 size_t len; 371 size_t len;
368 372
369 // TODO(erikkay): Yuck. I'm not a big fan of this kind of code, but it 373 // TODO(erikkay): Yuck. I'm not a big fan of this kind of code, but it
370 // appears that we don't have any endian/alignment aware serialization 374 // appears that we don't have any endian/alignment aware serialization
371 // code in the code base. So for now, this assumes that we're running 375 // code in the code base. So for now, this assumes that we're running
372 // on a little endian machine with 4 byte alignment. 376 // on a little endian machine with 4 byte alignment.
373 len = fread(&header, 1, sizeof(ExtensionHeader), 377 len = fread(&header, 1, sizeof(ExtensionHeader),
374 file.get()); 378 file.get());
375 if (len < sizeof(ExtensionHeader)) { 379 if (len < sizeof(ExtensionHeader)) {
376 // Invalid crx header 380 // Invalid crx header
377 ReportFailure( 381 ReportFailure(
378 CRX_HEADER_INVALID, 382 CRX_HEADER_INVALID,
379 l10n_util::GetStringFUTF8( 383 l10n_util::GetStringFUTF16(
380 IDS_EXTENSION_PACKAGE_ERROR_CODE, 384 IDS_EXTENSION_PACKAGE_ERROR_CODE,
381 ASCIIToUTF16("CRX_HEADER_INVALID"))); 385 ASCIIToUTF16("CRX_HEADER_INVALID")));
382 return false; 386 return false;
383 } 387 }
384 if (strncmp(kExtensionHeaderMagic, header.magic, 388 if (strncmp(kExtensionHeaderMagic, header.magic,
385 sizeof(header.magic))) { 389 sizeof(header.magic))) {
386 // Bad magic number 390 // Bad magic number
387 ReportFailure( 391 ReportFailure(
388 CRX_MAGIC_NUMBER_INVALID, 392 CRX_MAGIC_NUMBER_INVALID,
389 l10n_util::GetStringFUTF8( 393 l10n_util::GetStringFUTF16(
390 IDS_EXTENSION_PACKAGE_ERROR_CODE, 394 IDS_EXTENSION_PACKAGE_ERROR_CODE,
391 ASCIIToUTF16("CRX_MAGIC_NUMBER_INVALID"))); 395 ASCIIToUTF16("CRX_MAGIC_NUMBER_INVALID")));
392 return false; 396 return false;
393 } 397 }
394 if (header.version != kCurrentVersion) { 398 if (header.version != kCurrentVersion) {
395 // Bad version numer 399 // Bad version numer
396 ReportFailure(CRX_VERSION_NUMBER_INVALID, 400 ReportFailure(CRX_VERSION_NUMBER_INVALID,
397 l10n_util::GetStringFUTF8( 401 l10n_util::GetStringFUTF16(
398 IDS_EXTENSION_PACKAGE_ERROR_CODE, 402 IDS_EXTENSION_PACKAGE_ERROR_CODE,
399 ASCIIToUTF16("CRX_VERSION_NUMBER_INVALID"))); 403 ASCIIToUTF16("CRX_VERSION_NUMBER_INVALID")));
400 return false; 404 return false;
401 } 405 }
402 if (header.key_size > kMaxPublicKeySize || 406 if (header.key_size > kMaxPublicKeySize ||
403 header.signature_size > kMaxSignatureSize) { 407 header.signature_size > kMaxSignatureSize) {
404 // Excessively large key or signature 408 // Excessively large key or signature
405 ReportFailure( 409 ReportFailure(
406 CRX_EXCESSIVELY_LARGE_KEY_OR_SIGNATURE, 410 CRX_EXCESSIVELY_LARGE_KEY_OR_SIGNATURE,
407 l10n_util::GetStringFUTF8( 411 l10n_util::GetStringFUTF16(
408 IDS_EXTENSION_PACKAGE_ERROR_CODE, 412 IDS_EXTENSION_PACKAGE_ERROR_CODE,
409 ASCIIToUTF16("CRX_EXCESSIVELY_LARGE_KEY_OR_SIGNATURE"))); 413 ASCIIToUTF16("CRX_EXCESSIVELY_LARGE_KEY_OR_SIGNATURE")));
410 return false; 414 return false;
411 } 415 }
412 if (header.key_size == 0) { 416 if (header.key_size == 0) {
413 // Key length is zero 417 // Key length is zero
414 ReportFailure( 418 ReportFailure(
415 CRX_ZERO_KEY_LENGTH, 419 CRX_ZERO_KEY_LENGTH,
416 l10n_util::GetStringFUTF8( 420 l10n_util::GetStringFUTF16(
417 IDS_EXTENSION_PACKAGE_ERROR_CODE, 421 IDS_EXTENSION_PACKAGE_ERROR_CODE,
418 ASCIIToUTF16("CRX_ZERO_KEY_LENGTH"))); 422 ASCIIToUTF16("CRX_ZERO_KEY_LENGTH")));
419 return false; 423 return false;
420 } 424 }
421 if (header.signature_size == 0) { 425 if (header.signature_size == 0) {
422 // Signature length is zero 426 // Signature length is zero
423 ReportFailure( 427 ReportFailure(
424 CRX_ZERO_SIGNATURE_LENGTH, 428 CRX_ZERO_SIGNATURE_LENGTH,
425 l10n_util::GetStringFUTF8( 429 l10n_util::GetStringFUTF16(
426 IDS_EXTENSION_PACKAGE_ERROR_CODE, 430 IDS_EXTENSION_PACKAGE_ERROR_CODE,
427 ASCIIToUTF16("CRX_ZERO_SIGNATURE_LENGTH"))); 431 ASCIIToUTF16("CRX_ZERO_SIGNATURE_LENGTH")));
428 return false; 432 return false;
429 } 433 }
430 434
431 std::vector<uint8> key; 435 std::vector<uint8> key;
432 key.resize(header.key_size); 436 key.resize(header.key_size);
433 len = fread(&key.front(), sizeof(uint8), header.key_size, file.get()); 437 len = fread(&key.front(), sizeof(uint8), header.key_size, file.get());
434 if (len < header.key_size) { 438 if (len < header.key_size) {
435 // Invalid public key 439 // Invalid public key
436 ReportFailure( 440 ReportFailure(
437 CRX_PUBLIC_KEY_INVALID, 441 CRX_PUBLIC_KEY_INVALID,
438 l10n_util::GetStringFUTF8( 442 l10n_util::GetStringFUTF16(
439 IDS_EXTENSION_PACKAGE_ERROR_CODE, 443 IDS_EXTENSION_PACKAGE_ERROR_CODE,
440 ASCIIToUTF16("CRX_PUBLIC_KEY_INVALID"))); 444 ASCIIToUTF16("CRX_PUBLIC_KEY_INVALID")));
441 return false; 445 return false;
442 } 446 }
443 447
444 std::vector<uint8> signature; 448 std::vector<uint8> signature;
445 signature.resize(header.signature_size); 449 signature.resize(header.signature_size);
446 len = fread(&signature.front(), sizeof(uint8), header.signature_size, 450 len = fread(&signature.front(), sizeof(uint8), header.signature_size,
447 file.get()); 451 file.get());
448 if (len < header.signature_size) { 452 if (len < header.signature_size) {
449 // Invalid signature 453 // Invalid signature
450 ReportFailure( 454 ReportFailure(
451 CRX_SIGNATURE_INVALID, 455 CRX_SIGNATURE_INVALID,
452 l10n_util::GetStringFUTF8( 456 l10n_util::GetStringFUTF16(
453 IDS_EXTENSION_PACKAGE_ERROR_CODE, 457 IDS_EXTENSION_PACKAGE_ERROR_CODE,
454 ASCIIToUTF16("CRX_SIGNATURE_INVALID"))); 458 ASCIIToUTF16("CRX_SIGNATURE_INVALID")));
455 return false; 459 return false;
456 } 460 }
457 461
458 crypto::SignatureVerifier verifier; 462 crypto::SignatureVerifier verifier;
459 if (!verifier.VerifyInit(extension_misc::kSignatureAlgorithm, 463 if (!verifier.VerifyInit(extension_misc::kSignatureAlgorithm,
460 sizeof(extension_misc::kSignatureAlgorithm), 464 sizeof(extension_misc::kSignatureAlgorithm),
461 &signature.front(), 465 &signature.front(),
462 signature.size(), 466 signature.size(),
463 &key.front(), 467 &key.front(),
464 key.size())) { 468 key.size())) {
465 // Signature verification initialization failed. This is most likely 469 // Signature verification initialization failed. This is most likely
466 // caused by a public key in the wrong format (should encode algorithm). 470 // caused by a public key in the wrong format (should encode algorithm).
467 ReportFailure( 471 ReportFailure(
468 CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED, 472 CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED,
469 l10n_util::GetStringFUTF8( 473 l10n_util::GetStringFUTF16(
470 IDS_EXTENSION_PACKAGE_ERROR_CODE, 474 IDS_EXTENSION_PACKAGE_ERROR_CODE,
471 ASCIIToUTF16("CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED"))); 475 ASCIIToUTF16("CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED")));
472 return false; 476 return false;
473 } 477 }
474 478
475 unsigned char buf[1 << 12]; 479 unsigned char buf[1 << 12];
476 while ((len = fread(buf, 1, sizeof(buf), file.get())) > 0) 480 while ((len = fread(buf, 1, sizeof(buf), file.get())) > 0)
477 verifier.VerifyUpdate(buf, len); 481 verifier.VerifyUpdate(buf, len);
478 482
479 if (!verifier.VerifyFinal()) { 483 if (!verifier.VerifyFinal()) {
480 // Signature verification failed 484 // Signature verification failed
481 ReportFailure( 485 ReportFailure(
482 CRX_SIGNATURE_VERIFICATION_FAILED, 486 CRX_SIGNATURE_VERIFICATION_FAILED,
483 l10n_util::GetStringFUTF8( 487 l10n_util::GetStringFUTF16(
484 IDS_EXTENSION_PACKAGE_ERROR_CODE, 488 IDS_EXTENSION_PACKAGE_ERROR_CODE,
485 ASCIIToUTF16("CRX_SIGNATURE_VERIFICATION_FAILED"))); 489 ASCIIToUTF16("CRX_SIGNATURE_VERIFICATION_FAILED")));
486 return false; 490 return false;
487 } 491 }
488 492
489 base::Base64Encode(std::string(reinterpret_cast<char*>(&key.front()), 493 base::Base64Encode(std::string(reinterpret_cast<char*>(&key.front()),
490 key.size()), &public_key_); 494 key.size()), &public_key_);
491 return true; 495 return true;
492 } 496 }
493 497
494 void SandboxedExtensionUnpacker::ReportFailure(FailureReason reason, 498 void SandboxedExtensionUnpacker::ReportFailure(FailureReason reason,
495 const std::string& error) { 499 const string16& error) {
496 UMA_HISTOGRAM_ENUMERATION("Extensions.SandboxUnpackFailureReason", 500 UMA_HISTOGRAM_ENUMERATION("Extensions.SandboxUnpackFailureReason",
497 reason, NUM_FAILURE_REASONS); 501 reason, NUM_FAILURE_REASONS);
498 UMA_HISTOGRAM_TIMES("Extensions.SandboxUnpackFailureTime", 502 UMA_HISTOGRAM_TIMES("Extensions.SandboxUnpackFailureTime",
499 base::TimeTicks::Now() - unpack_start_time_); 503 base::TimeTicks::Now() - unpack_start_time_);
500 504
501 client_->OnUnpackFailure(error); 505 client_->OnUnpackFailure(error);
502 } 506 }
503 507
504 void SandboxedExtensionUnpacker::ReportSuccess( 508 void SandboxedExtensionUnpacker::ReportSuccess(
505 const DictionaryValue& original_manifest) { 509 const DictionaryValue& original_manifest) {
(...skipping 18 matching lines...) Expand all
524 scoped_ptr<DictionaryValue> final_manifest(manifest.DeepCopy()); 528 scoped_ptr<DictionaryValue> final_manifest(manifest.DeepCopy());
525 final_manifest->SetString(extension_manifest_keys::kPublicKey, public_key_); 529 final_manifest->SetString(extension_manifest_keys::kPublicKey, public_key_);
526 530
527 std::string manifest_json; 531 std::string manifest_json;
528 JSONStringValueSerializer serializer(&manifest_json); 532 JSONStringValueSerializer serializer(&manifest_json);
529 serializer.set_pretty_print(true); 533 serializer.set_pretty_print(true);
530 if (!serializer.Serialize(*final_manifest)) { 534 if (!serializer.Serialize(*final_manifest)) {
531 // Error serializing manifest.json. 535 // Error serializing manifest.json.
532 ReportFailure( 536 ReportFailure(
533 ERROR_SERIALIZING_MANIFEST_JSON, 537 ERROR_SERIALIZING_MANIFEST_JSON,
534 l10n_util::GetStringFUTF8( 538 l10n_util::GetStringFUTF16(
535 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 539 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
536 ASCIIToUTF16("ERROR_SERIALIZING_MANIFEST_JSON"))); 540 ASCIIToUTF16("ERROR_SERIALIZING_MANIFEST_JSON")));
537 return NULL; 541 return NULL;
538 } 542 }
539 543
540 FilePath manifest_path = 544 FilePath manifest_path =
541 extension_root_.Append(Extension::kManifestFilename); 545 extension_root_.Append(Extension::kManifestFilename);
542 if (!file_util::WriteFile(manifest_path, 546 if (!file_util::WriteFile(manifest_path,
543 manifest_json.data(), manifest_json.size())) { 547 manifest_json.data(), manifest_json.size())) {
544 // Error saving manifest.json. 548 // Error saving manifest.json.
545 ReportFailure( 549 ReportFailure(
546 ERROR_SAVING_MANIFEST_JSON, 550 ERROR_SAVING_MANIFEST_JSON,
547 l10n_util::GetStringFUTF8( 551 l10n_util::GetStringFUTF16(
548 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 552 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
549 ASCIIToUTF16("ERROR_SAVING_MANIFEST_JSON"))); 553 ASCIIToUTF16("ERROR_SAVING_MANIFEST_JSON")));
550 return NULL; 554 return NULL;
551 } 555 }
552 556
553 return final_manifest.release(); 557 return final_manifest.release();
554 } 558 }
555 559
556 bool SandboxedExtensionUnpacker::RewriteImageFiles() { 560 bool SandboxedExtensionUnpacker::RewriteImageFiles() {
557 ExtensionUnpacker::DecodedImages images; 561 ExtensionUnpacker::DecodedImages images;
558 if (!ExtensionUnpacker::ReadImagesFromFile(temp_dir_.path(), &images)) { 562 if (!ExtensionUnpacker::ReadImagesFromFile(temp_dir_.path(), &images)) {
559 // Couldn't read image data from disk. 563 // Couldn't read image data from disk.
560 ReportFailure( 564 ReportFailure(
561 COULD_NOT_READ_IMAGE_DATA_FROM_DISK, 565 COULD_NOT_READ_IMAGE_DATA_FROM_DISK,
562 l10n_util::GetStringFUTF8( 566 l10n_util::GetStringFUTF16(
563 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 567 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
564 ASCIIToUTF16("COULD_NOT_READ_IMAGE_DATA_FROM_DISK"))); 568 ASCIIToUTF16("COULD_NOT_READ_IMAGE_DATA_FROM_DISK")));
565 return false; 569 return false;
566 } 570 }
567 571
568 // Delete any images that may be used by the browser. We're going to write 572 // Delete any images that may be used by the browser. We're going to write
569 // out our own versions of the parsed images, and we want to make sure the 573 // out our own versions of the parsed images, and we want to make sure the
570 // originals are gone for good. 574 // originals are gone for good.
571 std::set<FilePath> image_paths = extension_->GetBrowserImages(); 575 std::set<FilePath> image_paths = extension_->GetBrowserImages();
572 if (image_paths.size() != images.size()) { 576 if (image_paths.size() != images.size()) {
573 // Decoded images don't match what's in the manifest. 577 // Decoded images don't match what's in the manifest.
574 ReportFailure( 578 ReportFailure(
575 DECODED_IMAGES_DO_NOT_MATCH_THE_MANIFEST, 579 DECODED_IMAGES_DO_NOT_MATCH_THE_MANIFEST,
576 l10n_util::GetStringFUTF8( 580 l10n_util::GetStringFUTF16(
577 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 581 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
578 ASCIIToUTF16("DECODED_IMAGES_DO_NOT_MATCH_THE_MANIFEST"))); 582 ASCIIToUTF16("DECODED_IMAGES_DO_NOT_MATCH_THE_MANIFEST")));
579 return false; 583 return false;
580 } 584 }
581 585
582 for (std::set<FilePath>::iterator it = image_paths.begin(); 586 for (std::set<FilePath>::iterator it = image_paths.begin();
583 it != image_paths.end(); ++it) { 587 it != image_paths.end(); ++it) {
584 FilePath path = *it; 588 FilePath path = *it;
585 if (path.IsAbsolute() || path.ReferencesParent()) { 589 if (path.IsAbsolute() || path.ReferencesParent()) {
586 // Invalid path for browser image. 590 // Invalid path for browser image.
587 ReportFailure( 591 ReportFailure(
588 INVALID_PATH_FOR_BROWSER_IMAGE, 592 INVALID_PATH_FOR_BROWSER_IMAGE,
589 l10n_util::GetStringFUTF8( 593 l10n_util::GetStringFUTF16(
590 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 594 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
591 ASCIIToUTF16("INVALID_PATH_FOR_BROWSER_IMAGE"))); 595 ASCIIToUTF16("INVALID_PATH_FOR_BROWSER_IMAGE")));
592 return false; 596 return false;
593 } 597 }
594 if (!file_util::Delete(extension_root_.Append(path), false)) { 598 if (!file_util::Delete(extension_root_.Append(path), false)) {
595 // Error removing old image file. 599 // Error removing old image file.
596 ReportFailure( 600 ReportFailure(
597 ERROR_REMOVING_OLD_IMAGE_FILE, 601 ERROR_REMOVING_OLD_IMAGE_FILE,
598 l10n_util::GetStringFUTF8( 602 l10n_util::GetStringFUTF16(
599 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 603 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
600 ASCIIToUTF16("ERROR_REMOVING_OLD_IMAGE_FILE"))); 604 ASCIIToUTF16("ERROR_REMOVING_OLD_IMAGE_FILE")));
601 return false; 605 return false;
602 } 606 }
603 } 607 }
604 608
605 // Write our parsed images back to disk as well. 609 // Write our parsed images back to disk as well.
606 for (size_t i = 0; i < images.size(); ++i) { 610 for (size_t i = 0; i < images.size(); ++i) {
607 const SkBitmap& image = images[i].a; 611 const SkBitmap& image = images[i].a;
608 FilePath path_suffix = images[i].b; 612 FilePath path_suffix = images[i].b;
609 if (path_suffix.IsAbsolute() || path_suffix.ReferencesParent()) { 613 if (path_suffix.IsAbsolute() || path_suffix.ReferencesParent()) {
610 // Invalid path for bitmap image. 614 // Invalid path for bitmap image.
611 ReportFailure( 615 ReportFailure(
612 INVALID_PATH_FOR_BITMAP_IMAGE, 616 INVALID_PATH_FOR_BITMAP_IMAGE,
613 l10n_util::GetStringFUTF8( 617 l10n_util::GetStringFUTF16(
614 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 618 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
615 ASCIIToUTF16("INVALID_PATH_FOR_BITMAP_IMAGE"))); 619 ASCIIToUTF16("INVALID_PATH_FOR_BITMAP_IMAGE")));
616 return false; 620 return false;
617 } 621 }
618 FilePath path = extension_root_.Append(path_suffix); 622 FilePath path = extension_root_.Append(path_suffix);
619 623
620 std::vector<unsigned char> image_data; 624 std::vector<unsigned char> image_data;
621 // TODO(mpcomplete): It's lame that we're encoding all images as PNG, even 625 // TODO(mpcomplete): It's lame that we're encoding all images as PNG, even
622 // though they may originally be .jpg, etc. Figure something out. 626 // though they may originally be .jpg, etc. Figure something out.
623 // http://code.google.com/p/chromium/issues/detail?id=12459 627 // http://code.google.com/p/chromium/issues/detail?id=12459
624 if (!gfx::PNGCodec::EncodeBGRASkBitmap(image, false, &image_data)) { 628 if (!gfx::PNGCodec::EncodeBGRASkBitmap(image, false, &image_data)) {
625 // Error re-encoding theme image. 629 // Error re-encoding theme image.
626 ReportFailure( 630 ReportFailure(
627 ERROR_RE_ENCODING_THEME_IMAGE, 631 ERROR_RE_ENCODING_THEME_IMAGE,
628 l10n_util::GetStringFUTF8( 632 l10n_util::GetStringFUTF16(
629 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 633 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
630 ASCIIToUTF16("ERROR_RE_ENCODING_THEME_IMAGE"))); 634 ASCIIToUTF16("ERROR_RE_ENCODING_THEME_IMAGE")));
631 return false; 635 return false;
632 } 636 }
633 637
634 // Note: we're overwriting existing files that the utility process wrote, 638 // Note: we're overwriting existing files that the utility process wrote,
635 // so we can be sure the directory exists. 639 // so we can be sure the directory exists.
636 const char* image_data_ptr = reinterpret_cast<const char*>(&image_data[0]); 640 const char* image_data_ptr = reinterpret_cast<const char*>(&image_data[0]);
637 if (!file_util::WriteFile(path, image_data_ptr, image_data.size())) { 641 if (!file_util::WriteFile(path, image_data_ptr, image_data.size())) {
638 // Error saving theme image. 642 // Error saving theme image.
639 ReportFailure( 643 ReportFailure(
640 ERROR_SAVING_THEME_IMAGE, 644 ERROR_SAVING_THEME_IMAGE,
641 l10n_util::GetStringFUTF8( 645 l10n_util::GetStringFUTF16(
642 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 646 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
643 ASCIIToUTF16("ERROR_SAVING_THEME_IMAGE"))); 647 ASCIIToUTF16("ERROR_SAVING_THEME_IMAGE")));
644 return false; 648 return false;
645 } 649 }
646 } 650 }
647 651
648 return true; 652 return true;
649 } 653 }
650 654
651 bool SandboxedExtensionUnpacker::RewriteCatalogFiles() { 655 bool SandboxedExtensionUnpacker::RewriteCatalogFiles() {
652 DictionaryValue catalogs; 656 DictionaryValue catalogs;
653 if (!ExtensionUnpacker::ReadMessageCatalogsFromFile(temp_dir_.path(), 657 if (!ExtensionUnpacker::ReadMessageCatalogsFromFile(temp_dir_.path(),
654 &catalogs)) { 658 &catalogs)) {
655 // Could not read catalog data from disk. 659 // Could not read catalog data from disk.
656 ReportFailure( 660 ReportFailure(
657 COULD_NOT_READ_CATALOG_DATA_FROM_DISK, 661 COULD_NOT_READ_CATALOG_DATA_FROM_DISK,
658 l10n_util::GetStringFUTF8( 662 l10n_util::GetStringFUTF16(
659 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 663 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
660 ASCIIToUTF16("COULD_NOT_READ_CATALOG_DATA_FROM_DISK"))); 664 ASCIIToUTF16("COULD_NOT_READ_CATALOG_DATA_FROM_DISK")));
661 return false; 665 return false;
662 } 666 }
663 667
664 // Write our parsed catalogs back to disk. 668 // Write our parsed catalogs back to disk.
665 for (DictionaryValue::key_iterator key_it = catalogs.begin_keys(); 669 for (DictionaryValue::key_iterator key_it = catalogs.begin_keys();
666 key_it != catalogs.end_keys(); ++key_it) { 670 key_it != catalogs.end_keys(); ++key_it) {
667 DictionaryValue* catalog; 671 DictionaryValue* catalog;
668 if (!catalogs.GetDictionaryWithoutPathExpansion(*key_it, &catalog)) { 672 if (!catalogs.GetDictionaryWithoutPathExpansion(*key_it, &catalog)) {
669 // Invalid catalog data. 673 // Invalid catalog data.
670 ReportFailure( 674 ReportFailure(
671 INVALID_CATALOG_DATA, 675 INVALID_CATALOG_DATA,
672 l10n_util::GetStringFUTF8( 676 l10n_util::GetStringFUTF16(
673 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 677 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
674 ASCIIToUTF16("INVALID_CATALOG_DATA"))); 678 ASCIIToUTF16("INVALID_CATALOG_DATA")));
675 return false; 679 return false;
676 } 680 }
677 681
678 // TODO(viettrungluu): Fix the |FilePath::FromWStringHack(UTF8ToWide())| 682 // TODO(viettrungluu): Fix the |FilePath::FromWStringHack(UTF8ToWide())|
679 // hack and remove the corresponding #include. 683 // hack and remove the corresponding #include.
680 FilePath relative_path = FilePath::FromWStringHack(UTF8ToWide(*key_it)); 684 FilePath relative_path = FilePath::FromWStringHack(UTF8ToWide(*key_it));
681 relative_path = relative_path.Append(Extension::kMessagesFilename); 685 relative_path = relative_path.Append(Extension::kMessagesFilename);
682 if (relative_path.IsAbsolute() || relative_path.ReferencesParent()) { 686 if (relative_path.IsAbsolute() || relative_path.ReferencesParent()) {
683 // Invalid path for catalog. 687 // Invalid path for catalog.
684 ReportFailure( 688 ReportFailure(
685 INVALID_PATH_FOR_CATALOG, 689 INVALID_PATH_FOR_CATALOG,
686 l10n_util::GetStringFUTF8( 690 l10n_util::GetStringFUTF16(
687 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 691 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
688 ASCIIToUTF16("INVALID_PATH_FOR_CATALOG"))); 692 ASCIIToUTF16("INVALID_PATH_FOR_CATALOG")));
689 return false; 693 return false;
690 } 694 }
691 FilePath path = extension_root_.Append(relative_path); 695 FilePath path = extension_root_.Append(relative_path);
692 696
693 std::string catalog_json; 697 std::string catalog_json;
694 JSONStringValueSerializer serializer(&catalog_json); 698 JSONStringValueSerializer serializer(&catalog_json);
695 serializer.set_pretty_print(true); 699 serializer.set_pretty_print(true);
696 if (!serializer.Serialize(*catalog)) { 700 if (!serializer.Serialize(*catalog)) {
697 // Error serializing catalog. 701 // Error serializing catalog.
698 ReportFailure( 702 ReportFailure(
699 ERROR_SERIALIZING_CATALOG, 703 ERROR_SERIALIZING_CATALOG,
700 l10n_util::GetStringFUTF8( 704 l10n_util::GetStringFUTF16(
701 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 705 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
702 ASCIIToUTF16("ERROR_SERIALIZING_CATALOG"))); 706 ASCIIToUTF16("ERROR_SERIALIZING_CATALOG")));
703 return false; 707 return false;
704 } 708 }
705 709
706 // Note: we're overwriting existing files that the utility process read, 710 // Note: we're overwriting existing files that the utility process read,
707 // so we can be sure the directory exists. 711 // so we can be sure the directory exists.
708 if (!file_util::WriteFile(path, 712 if (!file_util::WriteFile(path,
709 catalog_json.c_str(), 713 catalog_json.c_str(),
710 catalog_json.size())) { 714 catalog_json.size())) {
711 // Error saving catalog. 715 // Error saving catalog.
712 ReportFailure( 716 ReportFailure(
713 ERROR_SAVING_CATALOG, 717 ERROR_SAVING_CATALOG,
714 l10n_util::GetStringFUTF8( 718 l10n_util::GetStringFUTF16(
715 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 719 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
716 ASCIIToUTF16("ERROR_SAVING_CATALOG"))); 720 ASCIIToUTF16("ERROR_SAVING_CATALOG")));
717 return false; 721 return false;
718 } 722 }
719 } 723 }
720 724
721 return true; 725 return true;
722 } 726 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698