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

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(si): Continue removing std::string errors and replacing with string16
291 std::string std_error;
290 if (!extension_l10n_util::LocalizeExtension(extension_root_, 292 if (!extension_l10n_util::LocalizeExtension(extension_root_,
291 final_manifest.get(), 293 final_manifest.get(),
292 &error)) { 294 &std_error)) {
293 ReportFailure( 295 ReportFailure(
294 COULD_NOT_LOCALIZE_EXTENSION, 296 COULD_NOT_LOCALIZE_EXTENSION,
295 l10n_util::GetStringFUTF8( 297 l10n_util::GetStringFUTF16(
296 IDS_EXTENSION_PACKAGE_ERROR_MESSAGE, 298 IDS_EXTENSION_PACKAGE_ERROR_MESSAGE,
297 ASCIIToUTF16(error))); 299 UTF8ToUTF16(std_error)));
298 return; 300 return;
299 } 301 }
300 302
301 extension_ = Extension::Create( 303 extension_ = Extension::Create(
302 extension_root_, 304 extension_root_,
303 location_, 305 location_,
304 *final_manifest, 306 *final_manifest,
305 Extension::REQUIRE_KEY | creation_flags_, 307 Extension::REQUIRE_KEY | creation_flags_,
306 &error); 308 &std_error);
309
307 310
308 if (!extension_.get()) { 311 if (!extension_.get()) {
309 ReportFailure( 312 ReportFailure(
310 INVALID_MANIFEST, 313 INVALID_MANIFEST,
311 std::string("Manifest is invalid: ") + error); 314 ASCIIToUTF16("Manifest is invalid: " + std_error));
312 return; 315 return;
313 } 316 }
314 317
315 if (!RewriteImageFiles()) 318 if (!RewriteImageFiles())
316 return; 319 return;
317 320
318 if (!RewriteCatalogFiles()) 321 if (!RewriteCatalogFiles())
319 return; 322 return;
320 323
321 ReportSuccess(manifest); 324 ReportSuccess(manifest);
322 } 325 }
323 326
324 void SandboxedExtensionUnpacker::OnUnpackExtensionFailed( 327 void SandboxedExtensionUnpacker::OnUnpackExtensionFailed(
325 const std::string& error) { 328 const string16& error) {
326 CHECK(BrowserThread::CurrentlyOn(thread_identifier_)); 329 CHECK(BrowserThread::CurrentlyOn(thread_identifier_));
327 got_response_ = true; 330 got_response_ = true;
328 ReportFailure( 331 ReportFailure(
329 UNPACKER_CLIENT_FAILED, 332 UNPACKER_CLIENT_FAILED,
330 l10n_util::GetStringFUTF8( 333 l10n_util::GetStringFUTF16(
331 IDS_EXTENSION_PACKAGE_ERROR_MESSAGE, 334 IDS_EXTENSION_PACKAGE_ERROR_MESSAGE,
332 ASCIIToUTF16(error))); 335 error));
333 } 336 }
334 337
335 bool SandboxedExtensionUnpacker::ValidateSignature() { 338 bool SandboxedExtensionUnpacker::ValidateSignature() {
336 ScopedStdioHandle file(file_util::OpenFile(crx_path_, "rb")); 339 ScopedStdioHandle file(file_util::OpenFile(crx_path_, "rb"));
337 340
338 if (!file.get()) { 341 if (!file.get()) {
339 // Could not open crx file for reading. 342 // Could not open crx file for reading.
340 #if defined (OS_WIN) 343 #if defined (OS_WIN)
341 // On windows, get the error code. 344 // On windows, get the error code.
342 uint32 error_code = ::GetLastError(); 345 uint32 error_code = ::GetLastError();
343 // TODO(skerner): Use this histogram to understand why so many 346 // TODO(skerner): Use this histogram to understand why so many
344 // windows users hit this error. crbug.com/69693 347 // windows users hit this error. crbug.com/69693
345 348
346 // Windows errors are unit32s, but all of likely errors are in 349 // Windows errors are unit32s, but all of likely errors are in
347 // [1, 1000]. See winerror.h for the meaning of specific values. 350 // [1, 1000]. See winerror.h for the meaning of specific values.
348 // Clip errors outside the expected range to a single extra value. 351 // 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 352 // If there are errors in that extra bucket, we will know to expand
350 // the range. 353 // the range.
351 const uint32 kMaxErrorToSend = 1001; 354 const uint32 kMaxErrorToSend = 1001;
352 error_code = std::min(error_code, kMaxErrorToSend); 355 error_code = std::min(error_code, kMaxErrorToSend);
353 UMA_HISTOGRAM_ENUMERATION("Extensions.ErrorCodeFromCrxOpen", 356 UMA_HISTOGRAM_ENUMERATION("Extensions.ErrorCodeFromCrxOpen",
354 error_code, kMaxErrorToSend); 357 error_code, kMaxErrorToSend);
355 #endif 358 #endif
356 359
357 ReportFailure( 360 ReportFailure(
358 CRX_FILE_NOT_READABLE, 361 CRX_FILE_NOT_READABLE,
359 l10n_util::GetStringFUTF8( 362 l10n_util::GetStringFUTF16(
360 IDS_EXTENSION_PACKAGE_ERROR_CODE, 363 IDS_EXTENSION_PACKAGE_ERROR_CODE,
361 ASCIIToUTF16("CRX_FILE_NOT_READABLE"))); 364 ASCIIToUTF16("CRX_FILE_NOT_READABLE")));
362 return false; 365 return false;
363 } 366 }
364 367
365 // Read and verify the header. 368 // Read and verify the header.
366 ExtensionHeader header; 369 ExtensionHeader header;
367 size_t len; 370 size_t len;
368 371
369 // TODO(erikkay): Yuck. I'm not a big fan of this kind of code, but it 372 // 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 373 // 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 374 // code in the code base. So for now, this assumes that we're running
372 // on a little endian machine with 4 byte alignment. 375 // on a little endian machine with 4 byte alignment.
373 len = fread(&header, 1, sizeof(ExtensionHeader), 376 len = fread(&header, 1, sizeof(ExtensionHeader),
374 file.get()); 377 file.get());
375 if (len < sizeof(ExtensionHeader)) { 378 if (len < sizeof(ExtensionHeader)) {
376 // Invalid crx header 379 // Invalid crx header
377 ReportFailure( 380 ReportFailure(
378 CRX_HEADER_INVALID, 381 CRX_HEADER_INVALID,
379 l10n_util::GetStringFUTF8( 382 l10n_util::GetStringFUTF16(
380 IDS_EXTENSION_PACKAGE_ERROR_CODE, 383 IDS_EXTENSION_PACKAGE_ERROR_CODE,
381 ASCIIToUTF16("CRX_HEADER_INVALID"))); 384 ASCIIToUTF16("CRX_HEADER_INVALID")));
382 return false; 385 return false;
383 } 386 }
384 if (strncmp(kExtensionHeaderMagic, header.magic, 387 if (strncmp(kExtensionHeaderMagic, header.magic,
385 sizeof(header.magic))) { 388 sizeof(header.magic))) {
386 // Bad magic number 389 // Bad magic number
387 ReportFailure( 390 ReportFailure(
388 CRX_MAGIC_NUMBER_INVALID, 391 CRX_MAGIC_NUMBER_INVALID,
389 l10n_util::GetStringFUTF8( 392 l10n_util::GetStringFUTF16(
390 IDS_EXTENSION_PACKAGE_ERROR_CODE, 393 IDS_EXTENSION_PACKAGE_ERROR_CODE,
391 ASCIIToUTF16("CRX_MAGIC_NUMBER_INVALID"))); 394 ASCIIToUTF16("CRX_MAGIC_NUMBER_INVALID")));
392 return false; 395 return false;
393 } 396 }
394 if (header.version != kCurrentVersion) { 397 if (header.version != kCurrentVersion) {
395 // Bad version numer 398 // Bad version numer
396 ReportFailure(CRX_VERSION_NUMBER_INVALID, 399 ReportFailure(CRX_VERSION_NUMBER_INVALID,
397 l10n_util::GetStringFUTF8( 400 l10n_util::GetStringFUTF16(
398 IDS_EXTENSION_PACKAGE_ERROR_CODE, 401 IDS_EXTENSION_PACKAGE_ERROR_CODE,
399 ASCIIToUTF16("CRX_VERSION_NUMBER_INVALID"))); 402 ASCIIToUTF16("CRX_VERSION_NUMBER_INVALID")));
400 return false; 403 return false;
401 } 404 }
402 if (header.key_size > kMaxPublicKeySize || 405 if (header.key_size > kMaxPublicKeySize ||
403 header.signature_size > kMaxSignatureSize) { 406 header.signature_size > kMaxSignatureSize) {
404 // Excessively large key or signature 407 // Excessively large key or signature
405 ReportFailure( 408 ReportFailure(
406 CRX_EXCESSIVELY_LARGE_KEY_OR_SIGNATURE, 409 CRX_EXCESSIVELY_LARGE_KEY_OR_SIGNATURE,
407 l10n_util::GetStringFUTF8( 410 l10n_util::GetStringFUTF16(
408 IDS_EXTENSION_PACKAGE_ERROR_CODE, 411 IDS_EXTENSION_PACKAGE_ERROR_CODE,
409 ASCIIToUTF16("CRX_EXCESSIVELY_LARGE_KEY_OR_SIGNATURE"))); 412 ASCIIToUTF16("CRX_EXCESSIVELY_LARGE_KEY_OR_SIGNATURE")));
410 return false; 413 return false;
411 } 414 }
412 if (header.key_size == 0) { 415 if (header.key_size == 0) {
413 // Key length is zero 416 // Key length is zero
414 ReportFailure( 417 ReportFailure(
415 CRX_ZERO_KEY_LENGTH, 418 CRX_ZERO_KEY_LENGTH,
416 l10n_util::GetStringFUTF8( 419 l10n_util::GetStringFUTF16(
417 IDS_EXTENSION_PACKAGE_ERROR_CODE, 420 IDS_EXTENSION_PACKAGE_ERROR_CODE,
418 ASCIIToUTF16("CRX_ZERO_KEY_LENGTH"))); 421 ASCIIToUTF16("CRX_ZERO_KEY_LENGTH")));
419 return false; 422 return false;
420 } 423 }
421 if (header.signature_size == 0) { 424 if (header.signature_size == 0) {
422 // Signature length is zero 425 // Signature length is zero
423 ReportFailure( 426 ReportFailure(
424 CRX_ZERO_SIGNATURE_LENGTH, 427 CRX_ZERO_SIGNATURE_LENGTH,
425 l10n_util::GetStringFUTF8( 428 l10n_util::GetStringFUTF16(
426 IDS_EXTENSION_PACKAGE_ERROR_CODE, 429 IDS_EXTENSION_PACKAGE_ERROR_CODE,
427 ASCIIToUTF16("CRX_ZERO_SIGNATURE_LENGTH"))); 430 ASCIIToUTF16("CRX_ZERO_SIGNATURE_LENGTH")));
428 return false; 431 return false;
429 } 432 }
430 433
431 std::vector<uint8> key; 434 std::vector<uint8> key;
432 key.resize(header.key_size); 435 key.resize(header.key_size);
433 len = fread(&key.front(), sizeof(uint8), header.key_size, file.get()); 436 len = fread(&key.front(), sizeof(uint8), header.key_size, file.get());
434 if (len < header.key_size) { 437 if (len < header.key_size) {
435 // Invalid public key 438 // Invalid public key
436 ReportFailure( 439 ReportFailure(
437 CRX_PUBLIC_KEY_INVALID, 440 CRX_PUBLIC_KEY_INVALID,
438 l10n_util::GetStringFUTF8( 441 l10n_util::GetStringFUTF16(
439 IDS_EXTENSION_PACKAGE_ERROR_CODE, 442 IDS_EXTENSION_PACKAGE_ERROR_CODE,
440 ASCIIToUTF16("CRX_PUBLIC_KEY_INVALID"))); 443 ASCIIToUTF16("CRX_PUBLIC_KEY_INVALID")));
441 return false; 444 return false;
442 } 445 }
443 446
444 std::vector<uint8> signature; 447 std::vector<uint8> signature;
445 signature.resize(header.signature_size); 448 signature.resize(header.signature_size);
446 len = fread(&signature.front(), sizeof(uint8), header.signature_size, 449 len = fread(&signature.front(), sizeof(uint8), header.signature_size,
447 file.get()); 450 file.get());
448 if (len < header.signature_size) { 451 if (len < header.signature_size) {
449 // Invalid signature 452 // Invalid signature
450 ReportFailure( 453 ReportFailure(
451 CRX_SIGNATURE_INVALID, 454 CRX_SIGNATURE_INVALID,
452 l10n_util::GetStringFUTF8( 455 l10n_util::GetStringFUTF16(
453 IDS_EXTENSION_PACKAGE_ERROR_CODE, 456 IDS_EXTENSION_PACKAGE_ERROR_CODE,
454 ASCIIToUTF16("CRX_SIGNATURE_INVALID"))); 457 ASCIIToUTF16("CRX_SIGNATURE_INVALID")));
455 return false; 458 return false;
456 } 459 }
457 460
458 crypto::SignatureVerifier verifier; 461 crypto::SignatureVerifier verifier;
459 if (!verifier.VerifyInit(extension_misc::kSignatureAlgorithm, 462 if (!verifier.VerifyInit(extension_misc::kSignatureAlgorithm,
460 sizeof(extension_misc::kSignatureAlgorithm), 463 sizeof(extension_misc::kSignatureAlgorithm),
461 &signature.front(), 464 &signature.front(),
462 signature.size(), 465 signature.size(),
463 &key.front(), 466 &key.front(),
464 key.size())) { 467 key.size())) {
465 // Signature verification initialization failed. This is most likely 468 // Signature verification initialization failed. This is most likely
466 // caused by a public key in the wrong format (should encode algorithm). 469 // caused by a public key in the wrong format (should encode algorithm).
467 ReportFailure( 470 ReportFailure(
468 CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED, 471 CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED,
469 l10n_util::GetStringFUTF8( 472 l10n_util::GetStringFUTF16(
470 IDS_EXTENSION_PACKAGE_ERROR_CODE, 473 IDS_EXTENSION_PACKAGE_ERROR_CODE,
471 ASCIIToUTF16("CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED"))); 474 ASCIIToUTF16("CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED")));
472 return false; 475 return false;
473 } 476 }
474 477
475 unsigned char buf[1 << 12]; 478 unsigned char buf[1 << 12];
476 while ((len = fread(buf, 1, sizeof(buf), file.get())) > 0) 479 while ((len = fread(buf, 1, sizeof(buf), file.get())) > 0)
477 verifier.VerifyUpdate(buf, len); 480 verifier.VerifyUpdate(buf, len);
478 481
479 if (!verifier.VerifyFinal()) { 482 if (!verifier.VerifyFinal()) {
480 // Signature verification failed 483 // Signature verification failed
481 ReportFailure( 484 ReportFailure(
482 CRX_SIGNATURE_VERIFICATION_FAILED, 485 CRX_SIGNATURE_VERIFICATION_FAILED,
483 l10n_util::GetStringFUTF8( 486 l10n_util::GetStringFUTF16(
484 IDS_EXTENSION_PACKAGE_ERROR_CODE, 487 IDS_EXTENSION_PACKAGE_ERROR_CODE,
485 ASCIIToUTF16("CRX_SIGNATURE_VERIFICATION_FAILED"))); 488 ASCIIToUTF16("CRX_SIGNATURE_VERIFICATION_FAILED")));
486 return false; 489 return false;
487 } 490 }
488 491
489 base::Base64Encode(std::string(reinterpret_cast<char*>(&key.front()), 492 base::Base64Encode(std::string(reinterpret_cast<char*>(&key.front()),
490 key.size()), &public_key_); 493 key.size()), &public_key_);
491 return true; 494 return true;
492 } 495 }
493 496
494 void SandboxedExtensionUnpacker::ReportFailure(FailureReason reason, 497 void SandboxedExtensionUnpacker::ReportFailure(FailureReason reason,
495 const std::string& error) { 498 const string16& error) {
496 UMA_HISTOGRAM_ENUMERATION("Extensions.SandboxUnpackFailureReason", 499 UMA_HISTOGRAM_ENUMERATION("Extensions.SandboxUnpackFailureReason",
497 reason, NUM_FAILURE_REASONS); 500 reason, NUM_FAILURE_REASONS);
498 UMA_HISTOGRAM_TIMES("Extensions.SandboxUnpackFailureTime", 501 UMA_HISTOGRAM_TIMES("Extensions.SandboxUnpackFailureTime",
499 base::TimeTicks::Now() - unpack_start_time_); 502 base::TimeTicks::Now() - unpack_start_time_);
500 503
501 client_->OnUnpackFailure(error); 504 client_->OnUnpackFailure(error);
502 } 505 }
503 506
504 void SandboxedExtensionUnpacker::ReportSuccess( 507 void SandboxedExtensionUnpacker::ReportSuccess(
505 const DictionaryValue& original_manifest) { 508 const DictionaryValue& original_manifest) {
(...skipping 18 matching lines...) Expand all
524 scoped_ptr<DictionaryValue> final_manifest(manifest.DeepCopy()); 527 scoped_ptr<DictionaryValue> final_manifest(manifest.DeepCopy());
525 final_manifest->SetString(extension_manifest_keys::kPublicKey, public_key_); 528 final_manifest->SetString(extension_manifest_keys::kPublicKey, public_key_);
526 529
527 std::string manifest_json; 530 std::string manifest_json;
528 JSONStringValueSerializer serializer(&manifest_json); 531 JSONStringValueSerializer serializer(&manifest_json);
529 serializer.set_pretty_print(true); 532 serializer.set_pretty_print(true);
530 if (!serializer.Serialize(*final_manifest)) { 533 if (!serializer.Serialize(*final_manifest)) {
531 // Error serializing manifest.json. 534 // Error serializing manifest.json.
532 ReportFailure( 535 ReportFailure(
533 ERROR_SERIALIZING_MANIFEST_JSON, 536 ERROR_SERIALIZING_MANIFEST_JSON,
534 l10n_util::GetStringFUTF8( 537 l10n_util::GetStringFUTF16(
535 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 538 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
536 ASCIIToUTF16("ERROR_SERIALIZING_MANIFEST_JSON"))); 539 ASCIIToUTF16("ERROR_SERIALIZING_MANIFEST_JSON")));
537 return NULL; 540 return NULL;
538 } 541 }
539 542
540 FilePath manifest_path = 543 FilePath manifest_path =
541 extension_root_.Append(Extension::kManifestFilename); 544 extension_root_.Append(Extension::kManifestFilename);
542 if (!file_util::WriteFile(manifest_path, 545 if (!file_util::WriteFile(manifest_path,
543 manifest_json.data(), manifest_json.size())) { 546 manifest_json.data(), manifest_json.size())) {
544 // Error saving manifest.json. 547 // Error saving manifest.json.
545 ReportFailure( 548 ReportFailure(
546 ERROR_SAVING_MANIFEST_JSON, 549 ERROR_SAVING_MANIFEST_JSON,
547 l10n_util::GetStringFUTF8( 550 l10n_util::GetStringFUTF16(
548 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 551 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
549 ASCIIToUTF16("ERROR_SAVING_MANIFEST_JSON"))); 552 ASCIIToUTF16("ERROR_SAVING_MANIFEST_JSON")));
550 return NULL; 553 return NULL;
551 } 554 }
552 555
553 return final_manifest.release(); 556 return final_manifest.release();
554 } 557 }
555 558
556 bool SandboxedExtensionUnpacker::RewriteImageFiles() { 559 bool SandboxedExtensionUnpacker::RewriteImageFiles() {
557 ExtensionUnpacker::DecodedImages images; 560 ExtensionUnpacker::DecodedImages images;
558 if (!ExtensionUnpacker::ReadImagesFromFile(temp_dir_.path(), &images)) { 561 if (!ExtensionUnpacker::ReadImagesFromFile(temp_dir_.path(), &images)) {
559 // Couldn't read image data from disk. 562 // Couldn't read image data from disk.
560 ReportFailure( 563 ReportFailure(
561 COULD_NOT_READ_IMAGE_DATA_FROM_DISK, 564 COULD_NOT_READ_IMAGE_DATA_FROM_DISK,
562 l10n_util::GetStringFUTF8( 565 l10n_util::GetStringFUTF16(
563 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 566 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
564 ASCIIToUTF16("COULD_NOT_READ_IMAGE_DATA_FROM_DISK"))); 567 ASCIIToUTF16("COULD_NOT_READ_IMAGE_DATA_FROM_DISK")));
565 return false; 568 return false;
566 } 569 }
567 570
568 // Delete any images that may be used by the browser. We're going to write 571 // 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 572 // out our own versions of the parsed images, and we want to make sure the
570 // originals are gone for good. 573 // originals are gone for good.
571 std::set<FilePath> image_paths = extension_->GetBrowserImages(); 574 std::set<FilePath> image_paths = extension_->GetBrowserImages();
572 if (image_paths.size() != images.size()) { 575 if (image_paths.size() != images.size()) {
573 // Decoded images don't match what's in the manifest. 576 // Decoded images don't match what's in the manifest.
574 ReportFailure( 577 ReportFailure(
575 DECODED_IMAGES_DO_NOT_MATCH_THE_MANIFEST, 578 DECODED_IMAGES_DO_NOT_MATCH_THE_MANIFEST,
576 l10n_util::GetStringFUTF8( 579 l10n_util::GetStringFUTF16(
577 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 580 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
578 ASCIIToUTF16("DECODED_IMAGES_DO_NOT_MATCH_THE_MANIFEST"))); 581 ASCIIToUTF16("DECODED_IMAGES_DO_NOT_MATCH_THE_MANIFEST")));
579 return false; 582 return false;
580 } 583 }
581 584
582 for (std::set<FilePath>::iterator it = image_paths.begin(); 585 for (std::set<FilePath>::iterator it = image_paths.begin();
583 it != image_paths.end(); ++it) { 586 it != image_paths.end(); ++it) {
584 FilePath path = *it; 587 FilePath path = *it;
585 if (path.IsAbsolute() || path.ReferencesParent()) { 588 if (path.IsAbsolute() || path.ReferencesParent()) {
586 // Invalid path for browser image. 589 // Invalid path for browser image.
587 ReportFailure( 590 ReportFailure(
588 INVALID_PATH_FOR_BROWSER_IMAGE, 591 INVALID_PATH_FOR_BROWSER_IMAGE,
589 l10n_util::GetStringFUTF8( 592 l10n_util::GetStringFUTF16(
590 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 593 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
591 ASCIIToUTF16("INVALID_PATH_FOR_BROWSER_IMAGE"))); 594 ASCIIToUTF16("INVALID_PATH_FOR_BROWSER_IMAGE")));
592 return false; 595 return false;
593 } 596 }
594 if (!file_util::Delete(extension_root_.Append(path), false)) { 597 if (!file_util::Delete(extension_root_.Append(path), false)) {
595 // Error removing old image file. 598 // Error removing old image file.
596 ReportFailure( 599 ReportFailure(
597 ERROR_REMOVING_OLD_IMAGE_FILE, 600 ERROR_REMOVING_OLD_IMAGE_FILE,
598 l10n_util::GetStringFUTF8( 601 l10n_util::GetStringFUTF16(
599 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 602 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
600 ASCIIToUTF16("ERROR_REMOVING_OLD_IMAGE_FILE"))); 603 ASCIIToUTF16("ERROR_REMOVING_OLD_IMAGE_FILE")));
601 return false; 604 return false;
602 } 605 }
603 } 606 }
604 607
605 // Write our parsed images back to disk as well. 608 // Write our parsed images back to disk as well.
606 for (size_t i = 0; i < images.size(); ++i) { 609 for (size_t i = 0; i < images.size(); ++i) {
607 const SkBitmap& image = images[i].a; 610 const SkBitmap& image = images[i].a;
608 FilePath path_suffix = images[i].b; 611 FilePath path_suffix = images[i].b;
609 if (path_suffix.IsAbsolute() || path_suffix.ReferencesParent()) { 612 if (path_suffix.IsAbsolute() || path_suffix.ReferencesParent()) {
610 // Invalid path for bitmap image. 613 // Invalid path for bitmap image.
611 ReportFailure( 614 ReportFailure(
612 INVALID_PATH_FOR_BITMAP_IMAGE, 615 INVALID_PATH_FOR_BITMAP_IMAGE,
613 l10n_util::GetStringFUTF8( 616 l10n_util::GetStringFUTF16(
614 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 617 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
615 ASCIIToUTF16("INVALID_PATH_FOR_BITMAP_IMAGE"))); 618 ASCIIToUTF16("INVALID_PATH_FOR_BITMAP_IMAGE")));
616 return false; 619 return false;
617 } 620 }
618 FilePath path = extension_root_.Append(path_suffix); 621 FilePath path = extension_root_.Append(path_suffix);
619 622
620 std::vector<unsigned char> image_data; 623 std::vector<unsigned char> image_data;
621 // TODO(mpcomplete): It's lame that we're encoding all images as PNG, even 624 // 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. 625 // though they may originally be .jpg, etc. Figure something out.
623 // http://code.google.com/p/chromium/issues/detail?id=12459 626 // http://code.google.com/p/chromium/issues/detail?id=12459
624 if (!gfx::PNGCodec::EncodeBGRASkBitmap(image, false, &image_data)) { 627 if (!gfx::PNGCodec::EncodeBGRASkBitmap(image, false, &image_data)) {
625 // Error re-encoding theme image. 628 // Error re-encoding theme image.
626 ReportFailure( 629 ReportFailure(
627 ERROR_RE_ENCODING_THEME_IMAGE, 630 ERROR_RE_ENCODING_THEME_IMAGE,
628 l10n_util::GetStringFUTF8( 631 l10n_util::GetStringFUTF16(
629 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 632 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
630 ASCIIToUTF16("ERROR_RE_ENCODING_THEME_IMAGE"))); 633 ASCIIToUTF16("ERROR_RE_ENCODING_THEME_IMAGE")));
631 return false; 634 return false;
632 } 635 }
633 636
634 // Note: we're overwriting existing files that the utility process wrote, 637 // Note: we're overwriting existing files that the utility process wrote,
635 // so we can be sure the directory exists. 638 // so we can be sure the directory exists.
636 const char* image_data_ptr = reinterpret_cast<const char*>(&image_data[0]); 639 const char* image_data_ptr = reinterpret_cast<const char*>(&image_data[0]);
637 if (!file_util::WriteFile(path, image_data_ptr, image_data.size())) { 640 if (!file_util::WriteFile(path, image_data_ptr, image_data.size())) {
638 // Error saving theme image. 641 // Error saving theme image.
639 ReportFailure( 642 ReportFailure(
640 ERROR_SAVING_THEME_IMAGE, 643 ERROR_SAVING_THEME_IMAGE,
641 l10n_util::GetStringFUTF8( 644 l10n_util::GetStringFUTF16(
642 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 645 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
643 ASCIIToUTF16("ERROR_SAVING_THEME_IMAGE"))); 646 ASCIIToUTF16("ERROR_SAVING_THEME_IMAGE")));
644 return false; 647 return false;
645 } 648 }
646 } 649 }
647 650
648 return true; 651 return true;
649 } 652 }
650 653
651 bool SandboxedExtensionUnpacker::RewriteCatalogFiles() { 654 bool SandboxedExtensionUnpacker::RewriteCatalogFiles() {
652 DictionaryValue catalogs; 655 DictionaryValue catalogs;
653 if (!ExtensionUnpacker::ReadMessageCatalogsFromFile(temp_dir_.path(), 656 if (!ExtensionUnpacker::ReadMessageCatalogsFromFile(temp_dir_.path(),
654 &catalogs)) { 657 &catalogs)) {
655 // Could not read catalog data from disk. 658 // Could not read catalog data from disk.
656 ReportFailure( 659 ReportFailure(
657 COULD_NOT_READ_CATALOG_DATA_FROM_DISK, 660 COULD_NOT_READ_CATALOG_DATA_FROM_DISK,
658 l10n_util::GetStringFUTF8( 661 l10n_util::GetStringFUTF16(
659 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 662 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
660 ASCIIToUTF16("COULD_NOT_READ_CATALOG_DATA_FROM_DISK"))); 663 ASCIIToUTF16("COULD_NOT_READ_CATALOG_DATA_FROM_DISK")));
661 return false; 664 return false;
662 } 665 }
663 666
664 // Write our parsed catalogs back to disk. 667 // Write our parsed catalogs back to disk.
665 for (DictionaryValue::key_iterator key_it = catalogs.begin_keys(); 668 for (DictionaryValue::key_iterator key_it = catalogs.begin_keys();
666 key_it != catalogs.end_keys(); ++key_it) { 669 key_it != catalogs.end_keys(); ++key_it) {
667 DictionaryValue* catalog; 670 DictionaryValue* catalog;
668 if (!catalogs.GetDictionaryWithoutPathExpansion(*key_it, &catalog)) { 671 if (!catalogs.GetDictionaryWithoutPathExpansion(*key_it, &catalog)) {
669 // Invalid catalog data. 672 // Invalid catalog data.
670 ReportFailure( 673 ReportFailure(
671 INVALID_CATALOG_DATA, 674 INVALID_CATALOG_DATA,
672 l10n_util::GetStringFUTF8( 675 l10n_util::GetStringFUTF16(
673 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 676 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
674 ASCIIToUTF16("INVALID_CATALOG_DATA"))); 677 ASCIIToUTF16("INVALID_CATALOG_DATA")));
675 return false; 678 return false;
676 } 679 }
677 680
678 // TODO(viettrungluu): Fix the |FilePath::FromWStringHack(UTF8ToWide())| 681 // TODO(viettrungluu): Fix the |FilePath::FromWStringHack(UTF8ToWide())|
679 // hack and remove the corresponding #include. 682 // hack and remove the corresponding #include.
680 FilePath relative_path = FilePath::FromWStringHack(UTF8ToWide(*key_it)); 683 FilePath relative_path = FilePath::FromWStringHack(UTF8ToWide(*key_it));
681 relative_path = relative_path.Append(Extension::kMessagesFilename); 684 relative_path = relative_path.Append(Extension::kMessagesFilename);
682 if (relative_path.IsAbsolute() || relative_path.ReferencesParent()) { 685 if (relative_path.IsAbsolute() || relative_path.ReferencesParent()) {
683 // Invalid path for catalog. 686 // Invalid path for catalog.
684 ReportFailure( 687 ReportFailure(
685 INVALID_PATH_FOR_CATALOG, 688 INVALID_PATH_FOR_CATALOG,
686 l10n_util::GetStringFUTF8( 689 l10n_util::GetStringFUTF16(
687 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 690 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
688 ASCIIToUTF16("INVALID_PATH_FOR_CATALOG"))); 691 ASCIIToUTF16("INVALID_PATH_FOR_CATALOG")));
689 return false; 692 return false;
690 } 693 }
691 FilePath path = extension_root_.Append(relative_path); 694 FilePath path = extension_root_.Append(relative_path);
692 695
693 std::string catalog_json; 696 std::string catalog_json;
694 JSONStringValueSerializer serializer(&catalog_json); 697 JSONStringValueSerializer serializer(&catalog_json);
695 serializer.set_pretty_print(true); 698 serializer.set_pretty_print(true);
696 if (!serializer.Serialize(*catalog)) { 699 if (!serializer.Serialize(*catalog)) {
697 // Error serializing catalog. 700 // Error serializing catalog.
698 ReportFailure( 701 ReportFailure(
699 ERROR_SERIALIZING_CATALOG, 702 ERROR_SERIALIZING_CATALOG,
700 l10n_util::GetStringFUTF8( 703 l10n_util::GetStringFUTF16(
701 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 704 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
702 ASCIIToUTF16("ERROR_SERIALIZING_CATALOG"))); 705 ASCIIToUTF16("ERROR_SERIALIZING_CATALOG")));
703 return false; 706 return false;
704 } 707 }
705 708
706 // Note: we're overwriting existing files that the utility process read, 709 // Note: we're overwriting existing files that the utility process read,
707 // so we can be sure the directory exists. 710 // so we can be sure the directory exists.
708 if (!file_util::WriteFile(path, 711 if (!file_util::WriteFile(path,
709 catalog_json.c_str(), 712 catalog_json.c_str(),
710 catalog_json.size())) { 713 catalog_json.size())) {
711 // Error saving catalog. 714 // Error saving catalog.
712 ReportFailure( 715 ReportFailure(
713 ERROR_SAVING_CATALOG, 716 ERROR_SAVING_CATALOG,
714 l10n_util::GetStringFUTF8( 717 l10n_util::GetStringFUTF16(
715 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 718 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
716 ASCIIToUTF16("ERROR_SAVING_CATALOG"))); 719 ASCIIToUTF16("ERROR_SAVING_CATALOG")));
717 return false; 720 return false;
718 } 721 }
719 } 722 }
720 723
721 return true; 724 return true;
722 } 725 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698