function _Decryption_Loop() { // If legacy drop to legacy function if ($this->job['legacy']) { return $this->_Legacy_Decryption_Loop(); } // Grab the real block size and adjust the configured block size to ensure it is an exact divisor $real_blocksize = mcrypt_enc_get_block_size($this->cipher); $blocksize = $this->WPOnlineBackup->Get_Setting('max_block_size'); if (($rem = $blocksize % $real_blocksize) != 0) { $blocksize += $real_blocksize - $rem; } // Grab total length of data - increase it to block size and calculate the amount we'll need to trim after decryption $len = $this->job['header']['len']; if (($rem = $len % $real_blocksize) != 0) { $len += $trim = $real_blocksize - $rem; } else { $trim = 0; } // Take off what we've already done $len -= $this->job['done_bytes']; // Decrypt loop - if we've already done the last block break out while ($len - $trim > 0) { $block = min($blocksize, $len); if (($data = @fread($this->file, $block)) === false) { return OBFW_Exception(); } if (strlen($data) != $block) { return 'Partially read ' . strlen($data) . ' of ' . $block . ' bytes from encrypted data file for decryption.'; } // Change the IV for the next block to the encrypted data of the last block we're about to decrypt $this->job['current_iv'] = substr($data, $block - $real_blocksize, $real_blocksize); $data = mdecrypt_generic($this->cipher, $data); if (($len -= $block) <= 0) { if ($trim != 0) { $data = substr($data, 0, $trim * -1); } } $block = strlen($data); if (true !== ($ret = $this->stream->Write($data))) { return 'Write to stream failed. ' . $ret; } if ($this->hash_ctx !== false) { hash_update($this->hash_ctx, $data); $this->job['hash_len'] += $block; } else { if ($this->job['crc'] !== false) { $this->job['crc'] = WPOnlineBackup_Functions::Combine_CRC32($this->job['crc'], crc32($data), $block); } else { $this->job['crc'] = crc32($data); } } $this->job['done_bytes'] += $block; // Update the progress if ($this->job['done_bytes'] >= $this->job['header']['len']) { $this->job['progress'] = 99; } else { $this->job['progress'] = 10 + floor($this->job['done_bytes'] * 89 / $this->job['header']['len']); if ($this->job['progress'] > 99) { $this->job['progress'] = 99; } } $this->bootstrap->Tick(); } if ($this->hash_ctx !== false && $this->job['hash_len'] > 0) { list($crc) = array_values(unpack('N', hash_final($this->hash_ctx, true))); if ($this->job['crc'] !== false) { $this->job['crc'] = WPOnlineBackup_Functions::Combine_CRC32($this->job['crc'], $crc, $this->job['hash_len']); } else { $this->job['crc'] = $crc; } $this->hash_ctx = false; } if ($this->job['crc'] != $this->job['header']['crc']) { return false; } $this->bootstrap->Log_Event(WPONLINEBACKUP_EVENT_INFORMATION, 'File integrity check was successful.'); // Prevent duplicated messages $this->bootstrap->Tick(false, true); return true; }
function Commit_Stream() { // ASSERTION - We have just finalised a stream with End_Stream() and are ready to commit it $size = $this->rolling_size; // Did we never hit the large file size? If not, just store with normal deflation if ($size <= $this->WPOnlineBackup->Get_Setting('file_buffer_size')) { // Calculate CRC $crc = crc32($this->rolling_buffer); // Compress the data $this->rolling_buffer = gzdeflate($this->rolling_buffer); // Update the compressed data size $zlen = strlen($this->rolling_buffer); if (($ret = $this->writer->Write($this->rolling_buffer, $zlen)) !== true) { return $ret; } $this->rolling_buffer = false; // Already done everything neccessary, move out return compact('size', 'crc', 'zlen'); } // Finalize crc if we used hash_init if ($this->rolling_hash_ctx !== false) { list($inc_crc) = array_values(unpack('N', hash_final($this->rolling_hash_ctx, true))); $this->rolling_hash_ctx = false; if ($this->rolling_crc !== false) { $this->rolling_crc = WPOnlineBackup_Functions::Combine_CRC32($this->rolling_crc, $inc_crc, $this->rolling_hash_len); } else { $this->rolling_crc = $inc_crc; } } $crc = $this->rolling_crc; // Close and delete the buffer file $this->rolling_tempfile->CleanUp(); if ($this->register_temps) { $this->WPOnlineBackup->bootstrap->Unregister_Temp($this->rolling_tempfile->Get_File_Path()); } $this->rolling_tempfile = false; // Get the deflate stream size if (($zlen = @filesize($this->rolling_gzipname)) === false) { return OBFW_Exception(); } // Take away header and trailer $zlen -= 10 + 8; // Start to transfer the compressed data to our own file if (($f = @fopen($this->rolling_gzipname, 'rb')) === false) { return OBFW_Exception(); } // Skip the header if (@fseek($f, 10, SEEK_SET) != 0) { $e = OBFW_Exception(); @fclose($f); return $e; } // Start transferring $data = ''; while (!@feof($f)) { // Always get 8 extra bytes if (($extract = @fread($f, $this->WPOnlineBackup->Get_Setting('max_block_size') + 8)) === false) { $e = OBFW_Exception(); @fclose($f); return $e; } $data .= $extract; // Write all but the last 8 bytes $to_write = strlen($data) - 8; // Stop if we don't have anything to write if ($to_write == 0) { break; } // Write if (($ret = $this->writer->Write($data, $to_write)) !== true) { @fclose($f); return $ret; } // Leave the last 8 on the buffer $data = substr($data, -8); } // Clean up the tempfile @fclose($f); return compact('size', 'crc', 'zlen'); }
function Last_Write() { if ($this->hash_ctx !== false) { hash_update($this->hash_ctx, $this->data); $this->hash_len += $this->data_len; } else { if ($this->crc !== false) { $this->crc = WPOnlineBackup_Functions::Combine_CRC32($this->crc, crc32($this->data), $this->data_len); } else { $this->crc = crc32($this->data); } } // Encrypt remaining buffer in place - leave the padding $this->data = mcrypt_generic($this->cipher, $this->data); $len = strlen($this->data); $this->encsize += $len; // Write it if (($ret = $this->disk->Write($this->data, $len)) !== true) { return $ret; } // Clear the buffer $this->data = ''; $this->data_len = 0; return true; }
function Write_Stream($data, $len = false, $no_write = false) { // ASSERTION - We are currently in the middle of a stream deflation with Start_Stream // Since we always write directly because we have no compression to do, if we don't want to write, return false to say we want to if ($no_write) { return false; } // If len is false, use strlen(), otherwise truncate if ($len === false) { $len = strlen($data); } else { $data = substr($data, 0, $len); } // Add to size $this->rolling_size += $len; // Update crc and zlen if ($this->rolling_hash_ctx !== false) { hash_update($this->rolling_hash_ctx, $data); $this->rolling_hash_len += $len; } else { if ($this->rolling_crc !== false) { $this->rolling_crc = WPOnlineBackup_Functions::Combine_CRC32($this->rolling_crc, crc32($data), $len); } else { $this->rolling_crc = crc32($data); } } // Write the data if (($ret = $this->writer->Write($data, $len)) !== true) { return $ret; } return true; }