Version Description
- 01/26/2013 =
- Various changes to Google Drive authentication to help those who don't enter the correct details first time, or who later need to change accounts.
Download this release
Release Info
Developer | DavidAnderson |
Plugin | UpdraftPlus WordPress Backup Plugin |
Version | 1.3.14 |
Comparing to | |
See all releases |
Code changes from version 1.4.12 to 1.3.14
- includes/S3.php +12 -12
- methods/dropbox.php +9 -7
- methods/email.php +1 -1
- methods/ftp.php +3 -3
- methods/googledrive.php +13 -20
- methods/s3.php +38 -117
- options.php +11 -15
- readme.txt +59 -55
- trunk/example-decrypt.php +41 -0
- trunk/images/dropbox-logo.png +0 -0
- trunk/includes/Dropbox/API.php +583 -0
- trunk/includes/Dropbox/Exception.php +12 -0
- trunk/includes/Dropbox/OAuth/Consumer/ConsumerAbstract.php +307 -0
- trunk/includes/Dropbox/OAuth/Consumer/Curl.php +148 -0
- trunk/includes/Dropbox/OAuth/Consumer/WordPress.php +80 -0
- trunk/includes/Dropbox/OAuth/Consumer/ca-bundle.pem +3920 -0
- trunk/includes/Dropbox/OAuth/Storage/Encrypter.php +70 -0
- trunk/includes/Dropbox/OAuth/Storage/StorageInterface.php +30 -0
- trunk/includes/Dropbox/OAuth/Storage/WordPress.php +126 -0
- trunk/includes/Rijndael.php +1424 -0
- trunk/includes/S3.php +2211 -0
- trunk/includes/ajax.js +0 -0
- trunk/includes/class-gdocs.php +630 -0
- trunk/includes/ftp.class.php +194 -0
- trunk/includes/updraft-restorer.php +91 -0
- trunk/methods/dropbox.php +369 -0
- trunk/methods/email.php +30 -0
- trunk/methods/ftp.php +175 -0
- trunk/methods/googledrive.php +363 -0
- trunk/methods/s3.php +328 -0
- trunk/methods/template.php +71 -0
- trunk/options.php +93 -0
- trunk/readme.txt +335 -0
- trunk/updraftplus.php +2441 -0
- updraftplus.php +94 -433
includes/S3.php
CHANGED
@@ -535,19 +535,19 @@ class S3
|
|
535 |
$rest->setHeader('Content-Type', 'application/octet-stream');
|
536 |
$rest->data = "";
|
537 |
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
} else {
|
548 |
-
return false;
|
549 |
}
|
550 |
|
|
|
|
|
551 |
$rest->setHeader('Content-MD5', base64_encode(md5($rest->data, true)));
|
552 |
$rest->size = $bytes_read;
|
553 |
|
@@ -654,7 +654,7 @@ class S3
|
|
654 |
// Data
|
655 |
if (isset($input['fp']))
|
656 |
$rest->fp =& $input['fp'];
|
657 |
-
elseif (isset($input['file'])
|
658 |
$rest->fp = @fopen($input['file'], 'rb');
|
659 |
elseif (isset($input['data']))
|
660 |
$rest->data = $input['data'];
|
535 |
$rest->setHeader('Content-Type', 'application/octet-stream');
|
536 |
$rest->data = "";
|
537 |
|
538 |
+
$handle = fopen($filePath, "rb");
|
539 |
+
if ($fileOffset >0) fseek($handle, $fileOffset);
|
540 |
+
$bytes_read = 0;
|
541 |
+
|
542 |
+
while ($fileBytes >0) {
|
543 |
+
$read = fread($handle, min($fileBytes, 32768));
|
544 |
+
$fileBytes = $fileBytes - strlen($read);
|
545 |
+
$bytes_read += strlen($read);
|
546 |
+
$rest->data = $rest->data . $read;
|
|
|
|
|
547 |
}
|
548 |
|
549 |
+
fclose($handle);
|
550 |
+
|
551 |
$rest->setHeader('Content-MD5', base64_encode(md5($rest->data, true)));
|
552 |
$rest->size = $bytes_read;
|
553 |
|
654 |
// Data
|
655 |
if (isset($input['fp']))
|
656 |
$rest->fp =& $input['fp'];
|
657 |
+
elseif (isset($input['file']))
|
658 |
$rest->fp = @fopen($input['file'], 'rb');
|
659 |
elseif (isset($input['data']))
|
660 |
$rest->data = $input['data'];
|
methods/dropbox.php
CHANGED
@@ -11,12 +11,12 @@ class UpdraftPlus_BackupModule_dropbox {
|
|
11 |
global $updraftplus;
|
12 |
|
13 |
// Update upload ID
|
14 |
-
set_transient('updraf_dbid_'.$this->current_file_hash, $uploadid,
|
15 |
-
set_transient('updraf_dbof_'.$this->current_file_hash, $offset,
|
16 |
|
17 |
if ($this->current_file_size > 0) {
|
18 |
$percent = round(100*($offset/$this->current_file_size),1);
|
19 |
-
$updraftplus->
|
20 |
} else {
|
21 |
$updraftplus->log("Dropbox: Chunked Upload: $offset bytes uploaded");
|
22 |
}
|
@@ -206,7 +206,7 @@ class UpdraftPlus_BackupModule_dropbox {
|
|
206 |
|
207 |
}
|
208 |
|
209 |
-
|
210 |
|
211 |
?>
|
212 |
<tr class="updraftplusmethod dropbox">
|
@@ -291,7 +291,7 @@ class UpdraftPlus_BackupModule_dropbox {
|
|
291 |
<?php
|
292 |
}*/
|
293 |
|
294 |
-
|
295 |
if ( isset( $_GET['oauth_token'] ) ) {
|
296 |
self::auth_token();
|
297 |
} elseif (isset($_GET['updraftplus_dropboxauth'])) {
|
@@ -317,7 +317,7 @@ class UpdraftPlus_BackupModule_dropbox {
|
|
317 |
|
318 |
}
|
319 |
|
320 |
-
|
321 |
$previous_token = UpdraftPlus_Options::get_updraft_option("updraft_dropboxtk_request_token","xyz");
|
322 |
self::bootstrap();
|
323 |
$new_token = UpdraftPlus_Options::get_updraft_option("updraft_dropboxtk_request_token","xyz");
|
@@ -327,8 +327,10 @@ class UpdraftPlus_BackupModule_dropbox {
|
|
327 |
}
|
328 |
|
329 |
// Acquire single-use authorization code
|
330 |
-
|
|
|
331 |
self::bootstrap();
|
|
|
332 |
}
|
333 |
|
334 |
// This basically reproduces the relevant bits of bootstrap.php from the SDK
|
11 |
global $updraftplus;
|
12 |
|
13 |
// Update upload ID
|
14 |
+
set_transient('updraf_dbid_'.$this->current_file_hash, $uploadid, 3600*3);
|
15 |
+
set_transient('updraf_dbof_'.$this->current_file_hash, $offset, 3600*3);
|
16 |
|
17 |
if ($this->current_file_size > 0) {
|
18 |
$percent = round(100*($offset/$this->current_file_size),1);
|
19 |
+
$updraftplus->log("Dropbox: Chunked Upload: ${percent}% ($uploadid, $offset)");
|
20 |
} else {
|
21 |
$updraftplus->log("Dropbox: Chunked Upload: $offset bytes uploaded");
|
22 |
}
|
206 |
|
207 |
}
|
208 |
|
209 |
+
function config_print() {
|
210 |
|
211 |
?>
|
212 |
<tr class="updraftplusmethod dropbox">
|
291 |
<?php
|
292 |
}*/
|
293 |
|
294 |
+
function action_auth() {
|
295 |
if ( isset( $_GET['oauth_token'] ) ) {
|
296 |
self::auth_token();
|
297 |
} elseif (isset($_GET['updraftplus_dropboxauth'])) {
|
317 |
|
318 |
}
|
319 |
|
320 |
+
function auth_token() {
|
321 |
$previous_token = UpdraftPlus_Options::get_updraft_option("updraft_dropboxtk_request_token","xyz");
|
322 |
self::bootstrap();
|
323 |
$new_token = UpdraftPlus_Options::get_updraft_option("updraft_dropboxtk_request_token","xyz");
|
327 |
}
|
328 |
|
329 |
// Acquire single-use authorization code
|
330 |
+
function auth_request() {
|
331 |
+
|
332 |
self::bootstrap();
|
333 |
+
|
334 |
}
|
335 |
|
336 |
// This basically reproduces the relevant bits of bootstrap.php from the SDK
|
methods/email.php
CHANGED
@@ -16,7 +16,7 @@ class UpdraftPlus_BackupModule_email {
|
|
16 |
$updraftplus->prune_retained_backups("email", null, null);
|
17 |
}
|
18 |
|
19 |
-
|
20 |
?>
|
21 |
<tr class="updraftplusmethod email">
|
22 |
<th>Note:</th>
|
16 |
$updraftplus->prune_retained_backups("email", null, null);
|
17 |
}
|
18 |
|
19 |
+
function config_print() {
|
20 |
?>
|
21 |
<tr class="updraftplusmethod email">
|
22 |
<th>Note:</th>
|
methods/ftp.php
CHANGED
@@ -75,7 +75,7 @@ class UpdraftPlus_BackupModule_ftp {
|
|
75 |
$ftp->get($fullpath, $ftp_remote_path.$file, FTP_BINARY);
|
76 |
}
|
77 |
|
78 |
-
|
79 |
?>
|
80 |
jQuery('#updraft-ftp-test').click(function(){
|
81 |
var data = {
|
@@ -95,7 +95,7 @@ class UpdraftPlus_BackupModule_ftp {
|
|
95 |
<?php
|
96 |
}
|
97 |
|
98 |
-
|
99 |
?>
|
100 |
<tr class="updraftplusmethod ftp">
|
101 |
<th>FTP Server:</th>
|
@@ -120,7 +120,7 @@ class UpdraftPlus_BackupModule_ftp {
|
|
120 |
<?php
|
121 |
}
|
122 |
|
123 |
-
|
124 |
|
125 |
$server = $_POST['server'];
|
126 |
$login = $_POST['login'];
|
75 |
$ftp->get($fullpath, $ftp_remote_path.$file, FTP_BINARY);
|
76 |
}
|
77 |
|
78 |
+
function config_print_javascript_onready() {
|
79 |
?>
|
80 |
jQuery('#updraft-ftp-test').click(function(){
|
81 |
var data = {
|
95 |
<?php
|
96 |
}
|
97 |
|
98 |
+
function config_print() {
|
99 |
?>
|
100 |
<tr class="updraftplusmethod ftp">
|
101 |
<th>FTP Server:</th>
|
120 |
<?php
|
121 |
}
|
122 |
|
123 |
+
function credentials_test() {
|
124 |
|
125 |
$server = $_POST['server'];
|
126 |
$login = $_POST['login'];
|
methods/googledrive.php
CHANGED
@@ -5,7 +5,7 @@ class UpdraftPlus_BackupModule_googledrive {
|
|
5 |
var $gdocs;
|
6 |
var $gdocs_access_token;
|
7 |
|
8 |
-
|
9 |
if ( isset( $_GET['state'] ) ) {
|
10 |
if ( $_GET['state'] == 'token' )
|
11 |
self::gdrive_auth_token();
|
@@ -42,7 +42,7 @@ class UpdraftPlus_BackupModule_googledrive {
|
|
42 |
}
|
43 |
|
44 |
// Acquire single-use authorization code from Google OAuth 2.0
|
45 |
-
|
46 |
// First, revoke any existing token, since Google doesn't appear to like issuing new ones
|
47 |
if (UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token') != "") self::gdrive_auth_revoke();
|
48 |
// We use 'force' here for the approval_prompt, not 'auto', as that deals better with messy situations where the user authenticated, then changed settings
|
@@ -60,14 +60,14 @@ class UpdraftPlus_BackupModule_googledrive {
|
|
60 |
|
61 |
// Revoke a Google account refresh token
|
62 |
// Returns the parameter fed in, so can be used as a WordPress options filter
|
63 |
-
|
64 |
$ignore = wp_remote_get('https://accounts.google.com/o/oauth2/revoke?token='.UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token'));
|
65 |
UpdraftPlus_Options::update_updraft_option('updraft_googledrive_token','');
|
66 |
//header('Location: '.admin_url( 'options-general.php?page=updraftplus&message=Authorisation revoked'));
|
67 |
}
|
68 |
|
69 |
// Get a Google account refresh token using the code received from gdrive_auth_request
|
70 |
-
|
71 |
if( isset( $_GET['code'] ) ) {
|
72 |
$post_vars = array(
|
73 |
'code' => $_GET['code'],
|
@@ -80,13 +80,7 @@ class UpdraftPlus_BackupModule_googledrive {
|
|
80 |
$result = wp_remote_post('https://accounts.google.com/o/oauth2/token', array('timeout' => 30, 'method' => 'POST', 'body' => $post_vars) );
|
81 |
|
82 |
if (is_wp_error($result)) {
|
83 |
-
|
84 |
-
foreach ( $result->get_error_messages() as $message ) {
|
85 |
-
global $updraftplus;
|
86 |
-
$updraftplus->log("Google Drive authentication error: ".$message);
|
87 |
-
$add_to_url .= "$message. ";
|
88 |
-
}
|
89 |
-
header('Location: '.admin_url('options-general.php?page=updraftplus&error='.urlencode($add_to_url)) );
|
90 |
} else {
|
91 |
$json_values = json_decode( $result['body'], true );
|
92 |
if ( isset( $json_values['refresh_token'] ) ) {
|
@@ -113,7 +107,7 @@ class UpdraftPlus_BackupModule_googledrive {
|
|
113 |
// Do we have an access token?
|
114 |
if ( !$access_token = $this->access_token( UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token'), UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid'), UpdraftPlus_Options::get_updraft_option('updraft_googledrive_secret') )) {
|
115 |
$updraftplus->log('ERROR: Have not yet obtained an access token from Google (has the user authorised?)');
|
116 |
-
$updraftplus->error('Have not yet obtained an access token
|
117 |
return new WP_Error( "no_access_token", "Have not yet obtained an access token from Google (has the user authorised?");
|
118 |
}
|
119 |
|
@@ -200,13 +194,12 @@ class UpdraftPlus_BackupModule_googledrive {
|
|
200 |
// This counter is only used for when deciding what to log
|
201 |
$counter = 0;
|
202 |
do {
|
203 |
-
$log_string = ($counter == 0) ? "URL: $res" : "";
|
204 |
-
$updraftplus->record_uploaded_chunk($d, $log_string);
|
205 |
-
|
206 |
$counter++; if ($counter >= 20) $counter=0;
|
|
|
207 |
|
208 |
$res = $gdocs_object->upload_chunk();
|
209 |
-
if (is_string($res)) set_transient($transkey, $res,
|
210 |
$p = $gdocs_object->get_upload_percentage();
|
211 |
if ( $p - $d >= 1 ) {
|
212 |
$b = intval( $p - $d );
|
@@ -315,7 +308,7 @@ class UpdraftPlus_BackupModule_googledrive {
|
|
315 |
return false;
|
316 |
}
|
317 |
|
318 |
-
|
319 |
?>
|
320 |
<tr class="updraftplusmethod googledrive">
|
321 |
<td>Google Drive:</td>
|
@@ -327,7 +320,7 @@ class UpdraftPlus_BackupModule_googledrive {
|
|
327 |
<tr class="updraftplusmethod googledrive">
|
328 |
<th>Google Drive:</th>
|
329 |
<td>
|
330 |
-
<p><a href="http://
|
331 |
<p><a href="https://code.google.com/apis/console/">Follow this link to your Google API Console</a>, and there create a Client ID in the API Access section. Select 'Web Application' as the application type.</p><p>You must add <kbd><?php echo admin_url('options-general.php?page=updraftplus&action=updraftmethod-googledrive-auth'); ?></kbd> as the authorised redirect URI (under "More Options") when asked. N.B. If you install UpdraftPlus on several WordPress sites, then you cannot re-use your client ID; you must create a new one from your Google API console for each blog.
|
332 |
|
333 |
<?php
|
@@ -351,7 +344,7 @@ class UpdraftPlus_BackupModule_googledrive {
|
|
351 |
</tr>
|
352 |
<tr class="updraftplusmethod googledrive">
|
353 |
<th>Authenticate with Google:</th>
|
354 |
-
<td><p><?php if (UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token') != "") echo "<strong>(You appear to be already authenticated,</strong> though you can authenticate again to refresh your access if you've had a problem).</strong>"; ?> <a href="
|
355 |
</p>
|
356 |
</td>
|
357 |
</tr>
|
@@ -360,4 +353,4 @@ class UpdraftPlus_BackupModule_googledrive {
|
|
360 |
|
361 |
}
|
362 |
|
363 |
-
?>
|
5 |
var $gdocs;
|
6 |
var $gdocs_access_token;
|
7 |
|
8 |
+
function action_auth() {
|
9 |
if ( isset( $_GET['state'] ) ) {
|
10 |
if ( $_GET['state'] == 'token' )
|
11 |
self::gdrive_auth_token();
|
42 |
}
|
43 |
|
44 |
// Acquire single-use authorization code from Google OAuth 2.0
|
45 |
+
function gdrive_auth_request() {
|
46 |
// First, revoke any existing token, since Google doesn't appear to like issuing new ones
|
47 |
if (UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token') != "") self::gdrive_auth_revoke();
|
48 |
// We use 'force' here for the approval_prompt, not 'auto', as that deals better with messy situations where the user authenticated, then changed settings
|
60 |
|
61 |
// Revoke a Google account refresh token
|
62 |
// Returns the parameter fed in, so can be used as a WordPress options filter
|
63 |
+
function gdrive_auth_revoke() {
|
64 |
$ignore = wp_remote_get('https://accounts.google.com/o/oauth2/revoke?token='.UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token'));
|
65 |
UpdraftPlus_Options::update_updraft_option('updraft_googledrive_token','');
|
66 |
//header('Location: '.admin_url( 'options-general.php?page=updraftplus&message=Authorisation revoked'));
|
67 |
}
|
68 |
|
69 |
// Get a Google account refresh token using the code received from gdrive_auth_request
|
70 |
+
function gdrive_auth_token() {
|
71 |
if( isset( $_GET['code'] ) ) {
|
72 |
$post_vars = array(
|
73 |
'code' => $_GET['code'],
|
80 |
$result = wp_remote_post('https://accounts.google.com/o/oauth2/token', array('timeout' => 30, 'method' => 'POST', 'body' => $post_vars) );
|
81 |
|
82 |
if (is_wp_error($result)) {
|
83 |
+
header('Location: '.admin_url('options-general.php?page=updraftplus&error=' . __( 'Bad response!', 'backup' ) ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
} else {
|
85 |
$json_values = json_decode( $result['body'], true );
|
86 |
if ( isset( $json_values['refresh_token'] ) ) {
|
107 |
// Do we have an access token?
|
108 |
if ( !$access_token = $this->access_token( UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token'), UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid'), UpdraftPlus_Options::get_updraft_option('updraft_googledrive_secret') )) {
|
109 |
$updraftplus->log('ERROR: Have not yet obtained an access token from Google (has the user authorised?)');
|
110 |
+
$updraftplus->error('Have not yet obtained an access token frmo Google - you need to authorise or re-authorise your connection to Google Drive.');
|
111 |
return new WP_Error( "no_access_token", "Have not yet obtained an access token from Google (has the user authorised?");
|
112 |
}
|
113 |
|
194 |
// This counter is only used for when deciding what to log
|
195 |
$counter = 0;
|
196 |
do {
|
197 |
+
$log_string = ($counter == 0) ? "Upload %: $d, URL: $res" : "Upload %: $d";
|
|
|
|
|
198 |
$counter++; if ($counter >= 20) $counter=0;
|
199 |
+
$updraftplus->log($log_string);
|
200 |
|
201 |
$res = $gdocs_object->upload_chunk();
|
202 |
+
if (is_string($res)) set_transient($transkey, $res, 3600*3);
|
203 |
$p = $gdocs_object->get_upload_percentage();
|
204 |
if ( $p - $d >= 1 ) {
|
205 |
$b = intval( $p - $d );
|
308 |
return false;
|
309 |
}
|
310 |
|
311 |
+
function config_print() {
|
312 |
?>
|
313 |
<tr class="updraftplusmethod googledrive">
|
314 |
<td>Google Drive:</td>
|
320 |
<tr class="updraftplusmethod googledrive">
|
321 |
<th>Google Drive:</th>
|
322 |
<td>
|
323 |
+
<p><a href="http://david.dw-perspective.org.uk/da/index.php/computer-resources/updraftplus-googledrive-authorisation/"><strong>For longer help, including screenshots, follow this link. The description below is sufficient for more expert users.</strong></a></p>
|
324 |
<p><a href="https://code.google.com/apis/console/">Follow this link to your Google API Console</a>, and there create a Client ID in the API Access section. Select 'Web Application' as the application type.</p><p>You must add <kbd><?php echo admin_url('options-general.php?page=updraftplus&action=updraftmethod-googledrive-auth'); ?></kbd> as the authorised redirect URI (under "More Options") when asked. N.B. If you install UpdraftPlus on several WordPress sites, then you cannot re-use your client ID; you must create a new one from your Google API console for each blog.
|
325 |
|
326 |
<?php
|
344 |
</tr>
|
345 |
<tr class="updraftplusmethod googledrive">
|
346 |
<th>Authenticate with Google:</th>
|
347 |
+
<td><p><?php if (UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token') != "") echo "<strong>(You appear to be already authenticated,</strong> though you can authenticate again to refresh your access if you've had a problem).</strong>"; ?> <a href="?page=updraftplus&action=updraftmethod-googledrive-auth&updraftplus_googleauth=doit"><strong>After</strong> you have saved your settings (by clicking "Save Changes" below), then come back here once and click this link to complete authentication with Google.</a>
|
348 |
</p>
|
349 |
</td>
|
350 |
</tr>
|
353 |
|
354 |
}
|
355 |
|
356 |
+
?>
|
methods/s3.php
CHANGED
@@ -2,39 +2,13 @@
|
|
2 |
|
3 |
class UpdraftPlus_BackupModule_s3 {
|
4 |
|
5 |
-
function getS3($key, $secret) {
|
6 |
-
return new S3($key, $secret);
|
7 |
-
}
|
8 |
-
|
9 |
-
function set_endpoint($obj, $region) {
|
10 |
-
switch ($region) {
|
11 |
-
case 'EU':
|
12 |
-
case 'eu-west-1':
|
13 |
-
$endpoint = 's3-eu-west-1.amazonaws.com';
|
14 |
-
break;
|
15 |
-
case 'us-west-1':
|
16 |
-
case 'us-west-2':
|
17 |
-
case 'ap-southeast-1':
|
18 |
-
case 'ap-southeast-2':
|
19 |
-
case 'ap-northeast-1':
|
20 |
-
case 'sa-east-1':
|
21 |
-
$endpoint = 's3-'.$region.'.amazonaws.com';
|
22 |
-
break;
|
23 |
-
default:
|
24 |
-
break;
|
25 |
-
}
|
26 |
-
if (isset($endpoint)) {
|
27 |
-
$obj->setEndpoint($endpoint);
|
28 |
-
}
|
29 |
-
}
|
30 |
-
|
31 |
function backup($backup_array) {
|
32 |
|
33 |
global $updraftplus;
|
34 |
|
35 |
if (!class_exists('S3')) require_once(UPDRAFTPLUS_DIR.'/includes/S3.php');
|
36 |
|
37 |
-
$s3 =
|
38 |
|
39 |
$bucket_name = untrailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_s3_remote_path'));
|
40 |
$bucket_path = "";
|
@@ -45,26 +19,17 @@ class UpdraftPlus_BackupModule_s3 {
|
|
45 |
$bucket_path = $bmatches[2]."/";
|
46 |
}
|
47 |
|
48 |
-
$region = @$s3->getBucketLocation($bucket_name);
|
49 |
-
|
50 |
// See if we can detect the region (which implies the bucket exists and is ours), or if not create it
|
51 |
-
if (
|
52 |
-
|
53 |
-
if (empty($region)) $region = $s3->getBucketLocation($bucket_name);
|
54 |
-
$this->set_endpoint($s3, $region);
|
55 |
|
56 |
-
foreach($backup_array as $
|
57 |
|
58 |
// We upload in 5Mb chunks to allow more efficient resuming and hence uploading of larger files
|
59 |
-
// N.B.: 5Mb is Amazon's minimum. So don't go lower or you'll break it.
|
60 |
$fullpath = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dir')).$file;
|
61 |
-
$
|
62 |
-
$chunks = floor($orig_file_size / 5242880);
|
63 |
-
// There will be a remnant unless the file size was exactly on a 5Mb boundary
|
64 |
-
if ($orig_file_size % 5242880 > 0 ) $chunks++;
|
65 |
$hash = md5($file);
|
66 |
|
67 |
-
$updraftplus->log("S3 upload
|
68 |
|
69 |
$filepath = $bucket_path.$file;
|
70 |
|
@@ -82,23 +47,13 @@ class UpdraftPlus_BackupModule_s3 {
|
|
82 |
// Retrieve the upload ID
|
83 |
$uploadId = get_transient("updraft_${hash}_uid");
|
84 |
if (empty($uploadId)) {
|
85 |
-
$s3->
|
86 |
-
try {
|
87 |
-
$uploadId = $s3->initiateMultipartUpload($bucket_name, $filepath);
|
88 |
-
} catch (Exception $e) {
|
89 |
-
$updraftplus->log('S3 error whilst trying initiateMultipartUpload: '.$e->getMessage().' (line: '.$e->getLine().', file: '.$e->getFile().')');
|
90 |
-
$s3->setExceptions(false);
|
91 |
-
$uploadId = false;
|
92 |
-
}
|
93 |
-
$s3->setExceptions(false);
|
94 |
-
|
95 |
if (empty($uploadId)) {
|
96 |
-
$updraftplus->log("S3 upload: failed: could not get uploadId for multipart upload
|
97 |
-
$updraftplus->error("S3 upload: getting uploadID for multipart upload failed - see log file for more details");
|
98 |
continue;
|
99 |
} else {
|
100 |
$updraftplus->log("S3 chunked upload: got multipart ID: $uploadId");
|
101 |
-
set_transient("updraft_${hash}_uid", $uploadId,
|
102 |
}
|
103 |
} else {
|
104 |
$updraftplus->log("S3 chunked upload: retrieved previously obtained multipart ID: $uploadId");
|
@@ -114,15 +69,11 @@ class UpdraftPlus_BackupModule_s3 {
|
|
114 |
$successes++;
|
115 |
array_push($etags, $etag);
|
116 |
} else {
|
117 |
-
// Sanity check: we've seen a case where an overlap was truncating the file from underneath us
|
118 |
-
if (filesize($fullpath) < $orig_file_size) {
|
119 |
-
$updraftplus->error("S3 error: $key: chunk $i: file was truncated underneath us (orig_size=$orig_file_size, now_size=".filesize($fullpath).")");
|
120 |
-
}
|
121 |
$etag = $s3->uploadPart($bucket_name, $filepath, $uploadId, $fullpath, $i);
|
122 |
-
if (
|
123 |
-
$updraftplus->
|
124 |
array_push($etags, $etag);
|
125 |
-
set_transient("upd_${hash}_e$i", $etag,
|
126 |
$successes++;
|
127 |
} else {
|
128 |
$updraftplus->log("S3 chunk $i: upload failed");
|
@@ -132,22 +83,13 @@ class UpdraftPlus_BackupModule_s3 {
|
|
132 |
}
|
133 |
if ($successes >= $chunks) {
|
134 |
$updraftplus->log("S3 upload: all chunks uploaded; will now instruct S3 to re-assemble");
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
} else {
|
142 |
-
$updraftplus->log("S3 upload ($key): re-assembly failed");
|
143 |
-
$updraftplus->error("S3 upload ($key): re-assembly failed ($file)");
|
144 |
-
}
|
145 |
-
} catch (Exception $e) {
|
146 |
-
$updraftplus->log("S3 re-assembly error ($key): ".$e->getMessage().' (line: '.$e->getLine().', file: '.$e->getFile().')');
|
147 |
-
$updraftplus->error("S3 re-assembly error ($key): ".$e->getMessage().' (see log file for more)');
|
148 |
}
|
149 |
-
// Remember to unset, as the deletion code later reuses the object
|
150 |
-
$s3->setExceptions(false);
|
151 |
} else {
|
152 |
$updraftplus->log("S3 upload: upload was not completely successful on this run");
|
153 |
}
|
@@ -176,15 +118,16 @@ class UpdraftPlus_BackupModule_s3 {
|
|
176 |
}
|
177 |
$updraftplus->log("S3: Delete remote: bucket=$s3_bucket, URI=$s3_uri");
|
178 |
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
|
|
|
|
186 |
}
|
187 |
-
$s3->setExceptions(false);
|
188 |
|
189 |
}
|
190 |
|
@@ -193,19 +136,16 @@ class UpdraftPlus_BackupModule_s3 {
|
|
193 |
global $updraftplus;
|
194 |
if(!class_exists('S3')) require_once(UPDRAFTPLUS_DIR.'/includes/S3.php');
|
195 |
|
196 |
-
$s3 =
|
197 |
-
|
198 |
$bucket_name = untrailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_s3_remote_path'));
|
199 |
$bucket_path = "";
|
200 |
|
201 |
-
if (preg_match("#^([^/]+)/(.*)$#"
|
202 |
$bucket_name = $bmatches[1];
|
203 |
$bucket_path = $bmatches[2]."/";
|
204 |
}
|
205 |
|
206 |
-
|
207 |
-
if (!empty($region)) {
|
208 |
-
$this->set_endpoint($s3, $region);
|
209 |
$fullpath = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dir')).$file;
|
210 |
if (!$s3->getObject($bucket_name, $bucket_path.$file, $fullpath)) {
|
211 |
$updraftplus->error("S3 Error: Failed to download $file. Check your permissions and credentials.");
|
@@ -216,7 +156,7 @@ class UpdraftPlus_BackupModule_s3 {
|
|
216 |
|
217 |
}
|
218 |
|
219 |
-
|
220 |
?>
|
221 |
jQuery('#updraft-s3-test').click(function(){
|
222 |
var data = {
|
@@ -235,7 +175,7 @@ class UpdraftPlus_BackupModule_s3 {
|
|
235 |
<?php
|
236 |
}
|
237 |
|
238 |
-
|
239 |
|
240 |
?>
|
241 |
<tr class="updraftplusmethod s3">
|
@@ -266,19 +206,13 @@ class UpdraftPlus_BackupModule_s3 {
|
|
266 |
<?php
|
267 |
}
|
268 |
|
269 |
-
|
270 |
|
271 |
$key = $_POST['apikey'];
|
272 |
$secret = $_POST['apisecret'];
|
273 |
$path = $_POST['path'];
|
274 |
|
275 |
-
|
276 |
-
$bucket = $bmatches[1];
|
277 |
-
$path = $bmatches[2];
|
278 |
-
} else {
|
279 |
-
$bucket = $path;
|
280 |
-
$path = "";
|
281 |
-
}
|
282 |
|
283 |
if (empty($bucket)) {
|
284 |
echo "Failure: No bucket details were given.";
|
@@ -298,26 +232,13 @@ class UpdraftPlus_BackupModule_s3 {
|
|
298 |
|
299 |
$location = @$s3->getBucketLocation($bucket);
|
300 |
if ($location) {
|
301 |
-
$
|
302 |
-
$bucket_verb = "accessed (Amazon region: $location)";
|
303 |
-
$bucket_region = $location;
|
304 |
} else {
|
305 |
-
$
|
306 |
-
if ($
|
307 |
-
|
308 |
-
$bucket_exists = true;
|
309 |
-
} else {
|
310 |
-
echo "Failure: We could not successfully access or create such a bucket. Please check your access credentials, and if those are correct then try another bucket name (as another S3 user may already have taken your name).";
|
311 |
-
}
|
312 |
-
}
|
313 |
-
|
314 |
-
if (isset($bucket_exists)) {
|
315 |
-
$try_file = md5(rand());
|
316 |
-
if (!$s3->putObjectString($try_file, $bucket, $path.$try_file)) {
|
317 |
-
echo "Failure: We successfully $bucket_verb the bucket, but the attempt to create a file in it failed.";
|
318 |
} else {
|
319 |
-
echo "
|
320 |
-
@$s3->deleteObject($bucket, $path.$try_file);
|
321 |
}
|
322 |
}
|
323 |
|
2 |
|
3 |
class UpdraftPlus_BackupModule_s3 {
|
4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
function backup($backup_array) {
|
6 |
|
7 |
global $updraftplus;
|
8 |
|
9 |
if (!class_exists('S3')) require_once(UPDRAFTPLUS_DIR.'/includes/S3.php');
|
10 |
|
11 |
+
$s3 = new S3(UpdraftPlus_Options::get_updraft_option('updraft_s3_login'), UpdraftPlus_Options::get_updraft_option('updraft_s3_pass'));
|
12 |
|
13 |
$bucket_name = untrailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_s3_remote_path'));
|
14 |
$bucket_path = "";
|
19 |
$bucket_path = $bmatches[2]."/";
|
20 |
}
|
21 |
|
|
|
|
|
22 |
// See if we can detect the region (which implies the bucket exists and is ours), or if not create it
|
23 |
+
if (@$s3->getBucketLocation($bucket_name) || @$s3->putBucket($bucket_name, S3::ACL_PRIVATE)) {
|
|
|
|
|
|
|
24 |
|
25 |
+
foreach($backup_array as $file) {
|
26 |
|
27 |
// We upload in 5Mb chunks to allow more efficient resuming and hence uploading of larger files
|
|
|
28 |
$fullpath = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dir')).$file;
|
29 |
+
$chunks = floor(filesize($fullpath) / 5242880)+1;
|
|
|
|
|
|
|
30 |
$hash = md5($file);
|
31 |
|
32 |
+
$updraftplus->log("S3 upload: $fullpath (chunks: $chunks) -> s3://$bucket_name/$bucket_path$file");
|
33 |
|
34 |
$filepath = $bucket_path.$file;
|
35 |
|
47 |
// Retrieve the upload ID
|
48 |
$uploadId = get_transient("updraft_${hash}_uid");
|
49 |
if (empty($uploadId)) {
|
50 |
+
$uploadId = $s3->initiateMultipartUpload($bucket_name, $filepath);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
if (empty($uploadId)) {
|
52 |
+
$updraftplus->log("S3 upload: failed: could not get uploadId for multipart upload");
|
|
|
53 |
continue;
|
54 |
} else {
|
55 |
$updraftplus->log("S3 chunked upload: got multipart ID: $uploadId");
|
56 |
+
set_transient("updraft_${hash}_uid", $uploadId, 3600*3);
|
57 |
}
|
58 |
} else {
|
59 |
$updraftplus->log("S3 chunked upload: retrieved previously obtained multipart ID: $uploadId");
|
69 |
$successes++;
|
70 |
array_push($etags, $etag);
|
71 |
} else {
|
|
|
|
|
|
|
|
|
72 |
$etag = $s3->uploadPart($bucket_name, $filepath, $uploadId, $fullpath, $i);
|
73 |
+
if (is_string($etag)) {
|
74 |
+
$updraftplus->log("S3 chunk $i: uploaded (etag: $etag)");
|
75 |
array_push($etags, $etag);
|
76 |
+
set_transient("upd_${hash}_e$i", $etag, 3600*3);
|
77 |
$successes++;
|
78 |
} else {
|
79 |
$updraftplus->log("S3 chunk $i: upload failed");
|
83 |
}
|
84 |
if ($successes >= $chunks) {
|
85 |
$updraftplus->log("S3 upload: all chunks uploaded; will now instruct S3 to re-assemble");
|
86 |
+
if ($s3->completeMultipartUpload ($bucket_name, $filepath, $uploadId, $etags)) {
|
87 |
+
$updraftplus->log("S3 upload: re-assembly succeeded");
|
88 |
+
$updraftplus->uploaded_file($file);
|
89 |
+
} else {
|
90 |
+
$updraftplus->log("S3 upload: re-assembly failed");
|
91 |
+
$updraftplus->error("S3 upload: re-assembly failed ($file)");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
}
|
|
|
|
|
93 |
} else {
|
94 |
$updraftplus->log("S3 upload: upload was not completely successful on this run");
|
95 |
}
|
118 |
}
|
119 |
$updraftplus->log("S3: Delete remote: bucket=$s3_bucket, URI=$s3_uri");
|
120 |
|
121 |
+
# Here we brought in the contents of the S3.php function deleteObject in order to get more direct access to any error
|
122 |
+
$rest = new S3Request('DELETE', $s3_bucket, $s3_uri);
|
123 |
+
$rest = $rest->getResponse();
|
124 |
+
if ($rest->error === false && $rest->code !== 204) {
|
125 |
+
$updraftplus->log("S3 Error: Expected HTTP response 204; got: ".$rest->code);
|
126 |
+
//$updraftplus->error("S3 Error: Unexpected HTTP response code ".$rest->code." (expected 204)");
|
127 |
+
} elseif ($rest->error !== false) {
|
128 |
+
$updraftplus->log("S3 Error: ".$rest->error['code'].": ".$rest->error['message']);
|
129 |
+
//$updraftplus->error("S3 delete error: ".$rest->error['code'].": ".$rest->error['message']);
|
130 |
}
|
|
|
131 |
|
132 |
}
|
133 |
|
136 |
global $updraftplus;
|
137 |
if(!class_exists('S3')) require_once(UPDRAFTPLUS_DIR.'/includes/S3.php');
|
138 |
|
139 |
+
$s3 = new S3(UpdraftPlus_Options::get_updraft_option('updraft_s3_login'), UpdraftPlus_Options::get_updraft_option('updraft_s3_pass'));
|
|
|
140 |
$bucket_name = untrailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_s3_remote_path'));
|
141 |
$bucket_path = "";
|
142 |
|
143 |
+
if (preg_match("#^([^/]+)/(.*)$#",$bucket_name,$bmatches)) {
|
144 |
$bucket_name = $bmatches[1];
|
145 |
$bucket_path = $bmatches[2]."/";
|
146 |
}
|
147 |
|
148 |
+
if (@$s3->getBucketLocation($bucket_name)) {
|
|
|
|
|
149 |
$fullpath = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dir')).$file;
|
150 |
if (!$s3->getObject($bucket_name, $bucket_path.$file, $fullpath)) {
|
151 |
$updraftplus->error("S3 Error: Failed to download $file. Check your permissions and credentials.");
|
156 |
|
157 |
}
|
158 |
|
159 |
+
function config_print_javascript_onready() {
|
160 |
?>
|
161 |
jQuery('#updraft-s3-test').click(function(){
|
162 |
var data = {
|
175 |
<?php
|
176 |
}
|
177 |
|
178 |
+
function config_print() {
|
179 |
|
180 |
?>
|
181 |
<tr class="updraftplusmethod s3">
|
206 |
<?php
|
207 |
}
|
208 |
|
209 |
+
function credentials_test() {
|
210 |
|
211 |
$key = $_POST['apikey'];
|
212 |
$secret = $_POST['apisecret'];
|
213 |
$path = $_POST['path'];
|
214 |
|
215 |
+
$bucket = (preg_match("#^([^/]+)/(.*)$#", $path, $bmatches)) ? $bmatches[1] : $path;
|
|
|
|
|
|
|
|
|
|
|
|
|
216 |
|
217 |
if (empty($bucket)) {
|
218 |
echo "Failure: No bucket details were given.";
|
232 |
|
233 |
$location = @$s3->getBucketLocation($bucket);
|
234 |
if ($location) {
|
235 |
+
echo "Success: this bucket exists (Amazon region: $location) and we have access to it.";
|
|
|
|
|
236 |
} else {
|
237 |
+
$try_to_create = @$s3->putBucket($bucket, S3::ACL_PRIVATE);
|
238 |
+
if ($try_to_create) {
|
239 |
+
echo "Success: We have successfully created this bucket in your S3 account.";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
240 |
} else {
|
241 |
+
echo "Failure: We could not successfully access or create such a bucket. Please check your access credentials, and if those are correct then try another bucket name (as another S3 user may already have taken this name).";
|
|
|
242 |
}
|
243 |
}
|
244 |
|
options.php
CHANGED
@@ -5,33 +5,33 @@ if (!defined ('ABSPATH')) die ('No direct access allowed');
|
|
5 |
|
6 |
class UpdraftPlus_Options {
|
7 |
|
8 |
-
|
9 |
return current_user_can('manage_options');
|
10 |
}
|
11 |
|
12 |
-
|
13 |
return get_option($option, $default);
|
14 |
}
|
15 |
|
16 |
-
|
17 |
update_option($option, $value);
|
18 |
}
|
19 |
|
20 |
-
|
21 |
delete_option($option, $value);
|
22 |
}
|
23 |
|
24 |
-
|
25 |
global $updraftplus;
|
26 |
add_submenu_page('options-general.php', "UpdraftPlus", "UpdraftPlus", "manage_options", "updraftplus", array($updraftplus, "settings_output"));
|
27 |
}
|
28 |
|
29 |
-
|
30 |
echo '<form method="post" action="options.php">';
|
31 |
settings_fields('updraft-options-group');
|
32 |
}
|
33 |
|
34 |
-
|
35 |
|
36 |
global $updraftplus;
|
37 |
register_setting('updraft-options-group', 'updraft_interval', array($updraftplus, 'schedule_backup') );
|
@@ -66,21 +66,17 @@ class UpdraftPlus_Options {
|
|
66 |
register_setting('updraft-options-group', 'updraft_include_others', 'absint' );
|
67 |
register_setting('updraft-options-group', 'updraft_include_others_exclude' );
|
68 |
|
69 |
-
|
70 |
-
register_setting('updraft-options-group', 'updraft_starttime_db', array($updraftplus, 'hourminute') );
|
71 |
-
|
72 |
-
global $pagenow;
|
73 |
-
if (is_multisite() && $pagenow == 'options-general.php') {
|
74 |
add_action('admin_notices', array('UpdraftPlus_Options', 'show_admin_warning_multisite') );
|
75 |
}
|
76 |
|
77 |
}
|
78 |
|
79 |
-
|
80 |
|
81 |
global $updraftplus;
|
82 |
|
83 |
-
$updraftplus->show_admin_warning('<strong>UpdraftPlus warning:</strong> This is a WordPress multi-site (a.k.a. network) installation. <a href="http://updraftplus.com">WordPress Multisite is supported by UpdraftPlus Premium</a>. Non-premium UpdraftPlus does not support multi-site installations securely. <strong>Every</strong> blog admin can both back up (and hence access the data, including passwords, from) and restore (including with customised modifications, e.g. changed passwords) <strong>the entire network</strong>. Unless you are the only blog admin user across the entire network, you should immediately de-
|
84 |
|
85 |
}
|
86 |
|
@@ -90,4 +86,4 @@ class UpdraftPlus_Options {
|
|
90 |
add_action('admin_init', array('UpdraftPlus_Options', 'admin_init'));
|
91 |
add_action('admin_menu', array('UpdraftPlus_Options', 'add_admin_pages'));
|
92 |
|
93 |
-
?>
|
5 |
|
6 |
class UpdraftPlus_Options {
|
7 |
|
8 |
+
function user_can_manage() {
|
9 |
return current_user_can('manage_options');
|
10 |
}
|
11 |
|
12 |
+
function get_updraft_option($option, $default = null) {
|
13 |
return get_option($option, $default);
|
14 |
}
|
15 |
|
16 |
+
function update_updraft_option($option, $value) {
|
17 |
update_option($option, $value);
|
18 |
}
|
19 |
|
20 |
+
function delete_updraft_option($option) {
|
21 |
delete_option($option, $value);
|
22 |
}
|
23 |
|
24 |
+
function add_admin_pages() {
|
25 |
global $updraftplus;
|
26 |
add_submenu_page('options-general.php', "UpdraftPlus", "UpdraftPlus", "manage_options", "updraftplus", array($updraftplus, "settings_output"));
|
27 |
}
|
28 |
|
29 |
+
function options_form_begin() {
|
30 |
echo '<form method="post" action="options.php">';
|
31 |
settings_fields('updraft-options-group');
|
32 |
}
|
33 |
|
34 |
+
function admin_init() {
|
35 |
|
36 |
global $updraftplus;
|
37 |
register_setting('updraft-options-group', 'updraft_interval', array($updraftplus, 'schedule_backup') );
|
66 |
register_setting('updraft-options-group', 'updraft_include_others', 'absint' );
|
67 |
register_setting('updraft-options-group', 'updraft_include_others_exclude' );
|
68 |
|
69 |
+
if (is_multisite()) {
|
|
|
|
|
|
|
|
|
70 |
add_action('admin_notices', array('UpdraftPlus_Options', 'show_admin_warning_multisite') );
|
71 |
}
|
72 |
|
73 |
}
|
74 |
|
75 |
+
function show_admin_warning_multisite() {
|
76 |
|
77 |
global $updraftplus;
|
78 |
|
79 |
+
$updraftplus->show_admin_warning('<strong>UpdraftPlus warning:</strong> This is a WordPress multi-site (a.k.a. network) installation. <a href="http://updraftplus.com">WordPress Multisite is supported by UpdraftPlus Premium</a>. Non-premium UpdraftPlus does not support multi-site installations securely. <strong>Every</strong> blog admin can both back up (and hence access the data, including passwords, from) and restore (including with customised modifications, e.g. changed passwords) <strong>the entire network</strong>. Unless you are the only blog admin user across the entire network, you should immediately de-active UpdraftPlus. (This applies to all WordPress backup plugins unless they have been explicitly coded for multisite compatibility).', "error");
|
80 |
|
81 |
}
|
82 |
|
86 |
add_action('admin_init', array('UpdraftPlus_Options', 'admin_init'));
|
87 |
add_action('admin_menu', array('UpdraftPlus_Options', 'add_admin_pages'));
|
88 |
|
89 |
+
?>
|
readme.txt
CHANGED
@@ -3,17 +3,16 @@ Contributors: David Anderson
|
|
3 |
Tags: backup, restore, database, cloud, amazon, s3, dropbox, google drive, ftp, cloud, back up, multisite
|
4 |
Requires at least: 3.2
|
5 |
Tested up to: 3.5.1
|
6 |
-
Stable tag: 1.
|
7 |
-
Author URI: http://updraftplus.com
|
8 |
Donate link: http://david.dw-perspective.org.uk/donate
|
9 |
License: GPLv3 or later
|
10 |
|
11 |
== Upgrade Notice ==
|
12 |
-
|
13 |
|
14 |
== Description ==
|
15 |
|
16 |
-
|
17 |
|
18 |
* Supports backups to Amazon S3, Dropbox, Google Drive, FTP (including SSL), email
|
19 |
* One-click restore
|
@@ -24,37 +23,49 @@ Important fix for people backing up databases without encryption
|
|
24 |
* Database backups can be encrypted for security
|
25 |
* Debug mode that gives full logging of the backup
|
26 |
* Thousands of users: widely tested and reliable
|
27 |
-
* Premium/multi-site version
|
28 |
|
29 |
= Best New WordPress Plugin =
|
30 |
|
31 |
That's according to WordPress big cheese, Vladimir Prelovac. Check out his weekly chart to see where UpdraftPlus is right now: http://www.prelovac.com/vladimir/wordpress-plugins-rising-stars
|
32 |
|
33 |
-
=
|
34 |
-
|
35 |
-
UpdraftPlus is not crippled in any way - it is fully functional, with no annoying omissions. What we do have is various extra features, and guaranteed support, available <a href="http://updraftplus.com/">from our website, updraftplus.com</a>.
|
36 |
|
37 |
-
|
38 |
|
39 |
-
=
|
40 |
|
41 |
-
|
42 |
|
43 |
= Other support =
|
44 |
|
45 |
-
We hang out in the support forum for this plugin - http://wordpress.org/support/plugin/updraftplus - however, to save our time so that we can spend it on development, please read the plugin's Frequently Asked Questions -
|
46 |
|
47 |
== Installation ==
|
48 |
|
49 |
-
|
|
|
|
|
|
|
|
|
50 |
|
51 |
== Frequently Asked Questions ==
|
52 |
|
53 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
|
55 |
-
=
|
56 |
|
57 |
-
|
58 |
|
59 |
= I found a bug. What do I do? =
|
60 |
|
@@ -70,6 +81,24 @@ If you are a programmer and can send a patch, then that's even better.
|
|
70 |
|
71 |
Finally, if you post in the WordPress support forum, then make sure you include the word UpdraftPlus in your post; otherwise I will not be automatically notified that you posted.
|
72 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
= Anything essential to know? =
|
74 |
|
75 |
After you have set up UpdraftPlus, you must check that your backups are taking place successfully. WordPress is a complex piece of software that runs in many situations. Don't wait until you need your backups before you find out that they never worked in the first place. Remember, there's no warranty and no guarantees - this is free software.
|
@@ -84,12 +113,24 @@ You can check the changelog for changes; but the original Updraft, before I fork
|
|
84 |
|
85 |
= Any known bugs ? =
|
86 |
|
87 |
-
Not a bug, but one issue to be aware of is that backups of very large sites (lots of uploaded media) are quite complex matters, given the limits of running inside WordPress on a huge variety of different web hosting setups. With large sites, you need to use Amazon S3, which UpdraftPlus supports (since 0.9.20) or Google Drive (since 0.9.21) or Dropbox (since 1.2.19), because these support chunked, resumable uploads. Other backup methods have code (since 0.9.0) to retry failed uploads of an archive, but the upload cannot be chunked, so if an archive is enormous (i.e. cannot be completely uploaded in the time that PHP is allowed for running on your web host) it cannot work.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
|
89 |
= My site was hacked, and I have no backups! I thought UpdraftPlus was working! Can I kill you? =
|
90 |
|
91 |
No, there's no warranty or guarantee, etc. It's completely up to you to verify that UpdraftPlus is working correctly. If it doesn't then that's unfortunate, but this is a free plugin.
|
92 |
|
|
|
|
|
|
|
|
|
93 |
= I am not running the most recent version of UpdraftPlus. Should I upgrade? =
|
94 |
|
95 |
Yes; especially before you submit any support requests.
|
@@ -100,44 +141,7 @@ Thanks for asking - yes, I have. Check out my profile page - http://profiles.wor
|
|
100 |
|
101 |
== Changelog ==
|
102 |
|
103 |
-
= 1.
|
104 |
-
* Various branding tweaks - <a href="http://updraftplus.com">launch of updraftplus.com</a>
|
105 |
-
* Important fix for people with non-encrypted database backups
|
106 |
-
|
107 |
-
= 1.4.9 - 02/12/2013 =
|
108 |
-
* Do more when testing Amazon S3 connectivity (catches users with bucket but not file access)
|
109 |
-
* Tweak algorithm for detecting useful activity to further help gigantic sites
|
110 |
-
|
111 |
-
= 1.4.7 - 02/09/2013 =
|
112 |
-
* Tweak for some Amazon EU West 1 bucket users
|
113 |
-
|
114 |
-
= 1.4.6 - 02/07/2013 =
|
115 |
-
* Amazon S3 now works for users with non-US buckets
|
116 |
-
* Further tweak to overlap detection
|
117 |
-
|
118 |
-
= 1.4.2 - 02/06/2013 =
|
119 |
-
* More Amazon S3 logging which should help people with wrong details
|
120 |
-
* More race/overlap detection, and more flexible rescheduling
|
121 |
-
|
122 |
-
= 1.4.0 - 02/04/2013 =
|
123 |
-
* Zip file creation is now resumable; and thus the entire backup operation is; there is now no "too early to resume" point. So even the most enormous site backups should now be able to proceed.
|
124 |
-
* Prefer PHP's native zip functions if available - 25% speed-up on zip creation
|
125 |
-
|
126 |
-
= 1.3.22 - 01/31/2013 =
|
127 |
-
* More help for really large uploads; dynamically alter the maximum number of resumption attempts if something useful is still happening
|
128 |
-
|
129 |
-
= 1.3.20 - 01/30/2013 =
|
130 |
-
* Add extra error checking in S3 method (can prevent logging loop)
|
131 |
-
|
132 |
-
= 1.3.19 - 01/29/2013 =
|
133 |
-
* Since 1.3.3, the 'Last Backup' indicator in the control panel had not been updating
|
134 |
-
|
135 |
-
= 1.3.18 - 01/28/2013 =
|
136 |
-
* Made 'expert mode' easier to operate, and tidier options for non-expert users.
|
137 |
-
* Some (not total) compliance with PHP's strict coding standards mode
|
138 |
-
* More detail provided when failing to authorise with Google
|
139 |
-
|
140 |
-
= 1.3.15 - 01/26/2013 =
|
141 |
* Various changes to Google Drive authentication to help those who don't enter the correct details first time, or who later need to change accounts.
|
142 |
|
143 |
= 1.3.12 - 01/25/2013 =
|
3 |
Tags: backup, restore, database, cloud, amazon, s3, dropbox, google drive, ftp, cloud, back up, multisite
|
4 |
Requires at least: 3.2
|
5 |
Tested up to: 3.5.1
|
6 |
+
Stable tag: 1.3.14
|
|
|
7 |
Donate link: http://david.dw-perspective.org.uk/donate
|
8 |
License: GPLv3 or later
|
9 |
|
10 |
== Upgrade Notice ==
|
11 |
+
Essential bugfix release for all earlier releases
|
12 |
|
13 |
== Description ==
|
14 |
|
15 |
+
UpdraftPlus simplifies backups (and restoration). Backup into the cloud (Amazon S3, Dropbox, Google Drive, FTP, and email) and restore with a single click. Backups of files and database can have separate schedules.
|
16 |
|
17 |
* Supports backups to Amazon S3, Dropbox, Google Drive, FTP (including SSL), email
|
18 |
* One-click restore
|
23 |
* Database backups can be encrypted for security
|
24 |
* Debug mode that gives full logging of the backup
|
25 |
* Thousands of users: widely tested and reliable
|
26 |
+
* Premium/multi-site version available (see below)
|
27 |
|
28 |
= Best New WordPress Plugin =
|
29 |
|
30 |
That's according to WordPress big cheese, Vladimir Prelovac. Check out his weekly chart to see where UpdraftPlus is right now: http://www.prelovac.com/vladimir/wordpress-plugins-rising-stars
|
31 |
|
32 |
+
= Professional / Enterprise support agreements available =
|
|
|
|
|
33 |
|
34 |
+
UpdraftPlus is written by professional WordPress developers. If your site needs guaranteed support, then we are available. Get in touch - https://www.simbahosting.co.uk/s3/products-and-services/wordpress-experts/ - to arrange the support contract that your site needs.
|
35 |
|
36 |
+
= UpdraftPlus Premium =
|
37 |
|
38 |
+
If you need WordPress multisite compatibility (you'll know if you do), then you need UpdraftPlus Premium: http://updraftplus.com
|
39 |
|
40 |
= Other support =
|
41 |
|
42 |
+
We hang out in the support forum for this plugin - http://wordpress.org/support/plugin/updraftplus - however, to save our time so that we can spend it on development, please read the plugin's Frequently Asked Questions - http://wordpress.org/extend/plugins/updraftplus/faq/ - before going there, and ensure that you have updated to the latest released version of UpdraftPlus.
|
43 |
|
44 |
== Installation ==
|
45 |
|
46 |
+
Standard WordPress plugin installation:
|
47 |
+
|
48 |
+
1. Search for "UpdraftPlus" in your site's admin area plugin page
|
49 |
+
2. Press 'Install'
|
50 |
+
3. Go to the options page and go through the questions there
|
51 |
|
52 |
== Frequently Asked Questions ==
|
53 |
|
54 |
+
= What exactly does UpdraftPlus back up ? =
|
55 |
+
|
56 |
+
Basically, everything, unless you did something very exotic (which you would then know about) to your WordPress install. Unless you disable any of these, it will back up your database (all tables which have been prefixed with the prefix for this WordPress installation, both core tables and extra ones added by plugins), your plugins folder, your themes folder, your uploads folder and any extra folders that other plugins have created in the WordPress content directory.
|
57 |
+
|
58 |
+
= What does UpdraftPlus not back up ? =
|
59 |
+
|
60 |
+
It does not back up WordPress core (since you can always get another copy of this from wordpress.org), and does not back up any extra files which you have added outside of the WordPress content directory (files which, by their nature, are unknown to WordPress). By default the WordPress content directory is "wp-content" in your WordPress root. It will not back up database tables which do not have the WordPress prefix (i.e. database tables from other applications but sharing a database with WordPress).
|
61 |
+
|
62 |
+
= I like automating WordPress, and using the command-line. Please tell me more. =
|
63 |
+
|
64 |
+
That's very good of you, thank you. You are looking for WordShell, <a href="http://wordshell.net">http://wordshell.net</a>.
|
65 |
|
66 |
+
= Is it WordPress Multisite (a.k.a. WordPress network) compatible? =
|
67 |
|
68 |
+
If you have a WordPress Multisite install (and you'll know if you do), then you need <a href="http://updraftplus.com">UpdraftPlus Premium</a>.
|
69 |
|
70 |
= I found a bug. What do I do? =
|
71 |
|
81 |
|
82 |
Finally, if you post in the WordPress support forum, then make sure you include the word UpdraftPlus in your post; otherwise I will not be automatically notified that you posted.
|
83 |
|
84 |
+
= My scheduled backups and pressing "Backup Now" does nothing; however pressing "Debug Backup" does produce a backup =
|
85 |
+
|
86 |
+
This almost always indicates a problem with the scheduler in your WordPress installation. Schedule a backup (by pressing "Backup Now"), wait 5 seconds, and then run the wp-cron.php script on your site (e.g. http://example.com/wp-cron.php). If absolutely nothing happens (i.e. no log file appears in your wp-content/updraft directory), then you should contact your web hosting provider. We have heard of web hosting providers who have disabled this part of WordPress. Also, it is possible for other plugins to accidentally do this. Disable any cacheing plugins (e.g. WP Super Cache, WP Total Cache), plus any others that you can temporarily live without, and try the backup again. If the backup then succeeds, then you need to report the bug to the author of the guilty plugin.
|
87 |
+
|
88 |
+
= Some of my files have uploaded into my cloud storage, but not others. =
|
89 |
+
|
90 |
+
From version 0.9.0, UpdraftPlus features a resumption feature - if you wait 5 minutes and visit a page on your site, then it should re-try not-yet-uploaded files. If that fails, then turn on debugging and paste the debug log (log in via FTP, and look in wp-content/updraft) into the support forum. Before asking for support, make sure that you: 1) Have started a backup, and then waited at least an hour (because UpdraftPlus will keep trying) 2) Not started any new backups in the mean-time (that may cancel the earlier backup) 3) Have the log of the failed backup attempt, and that log only (please don't bombard me with every log file you could find - this only slows me down).
|
91 |
+
|
92 |
+
= How do I restore my backup (from a site that is still installed/running)? =
|
93 |
+
|
94 |
+
If your site is still basically intact (in particular, the database), and if you backed up using a cloud method (e.g. Amazon S3, Google Drive, FTP), then on the UpdraftPlus settings page, there is a nice shiny 'Restore' button. Press it, and it will over-write your present files (not database) with those contained in the indicated backup set.
|
95 |
+
|
96 |
+
Again, if you backed up using a cloud method, then on UpdraftPlus's settings page, there should be a clickable link next to "Download Backups". Click on that link, and it will give you a set of further buttons, allowing you to download zip files of the various backed-up components. You can download those to your computer, and then unpack them, and copy them into your web space. (That's a very simple operation - but if you don't know how and don't have a friend to assist, then bung me a donation - http://david.dw-perspective.org.uk/donate - and I can help out).
|
97 |
+
|
98 |
+
= I want to restore, but have either cannot, or have failed to do so from the WP Admin console =
|
99 |
+
|
100 |
+
That's no problem. If you have access to your backed files (i.e. you have the emailed copies, or have obtained the backed up copies directly from Amazon S3, Dropbox, Google Drive, FTP or whatever store you were using), then you simply need to unzip them into the right places. UpdraftPlus does not back up the WordPress core - you can just get a fresh copy of that from www.wordpress.org. So, if you are starting from nothing, then first download and unzip a WordPress zip from www.wordpress.org. After doing that, then unzip the zip files for your uploads, themes, plugins and other filesback into the wp-content directory. Then re-install the database (e.g. by running it through PHPMyAdmin - see also the later question on how to decrypt if your database backup was encrypted). These are all basic operations and not difficult for anyone with simple skills; but if you need help and cannot find someone to assist, then send me a meaningful donation - http://david.dw-perspective.org.uk/donate - and I can help.
|
101 |
+
|
102 |
= Anything essential to know? =
|
103 |
|
104 |
After you have set up UpdraftPlus, you must check that your backups are taking place successfully. WordPress is a complex piece of software that runs in many situations. Don't wait until you need your backups before you find out that they never worked in the first place. Remember, there's no warranty and no guarantees - this is free software.
|
113 |
|
114 |
= Any known bugs ? =
|
115 |
|
116 |
+
Not a bug as such, but one issue to be aware of is that backups of very large sites (lots of uploaded media) are quite complex matters, given the limits of running inside WordPress on a huge variety of different web hosting setups. With large sites, you need to use Amazon S3, which UpdraftPlus supports (since 0.9.20) or Google Drive (since 0.9.21) or Dropbox (since 1.2.19), because these support chunked, resumable uploads. Other backup methods have code (since 0.9.0) to retry failed uploads of an archive, but the upload cannot be chunked, so if an archive is enormous (i.e. cannot be completely uploaded in the time that PHP is allowed for running on your web host) it cannot work.
|
117 |
+
|
118 |
+
= I encrypted my database - how do I decrypt it? =
|
119 |
+
|
120 |
+
If you have the encryption key entered in your settings and you are restoring from the settings interface, then it will automatically decrypt. Otherwise, use the file example-decrypt.php found in the plugin directory; that will need very (very) minor PHP knowledge to use; find your local PHP guru, or bung me a donation (http://david.dw-perspective.org.uk/donate) and I can do it for you.
|
121 |
+
|
122 |
+
= I lost my encryption key - what can I do? =
|
123 |
+
|
124 |
+
Nothing, probably. That's the point of an encryption key - people who don't have it can't get the data. Hire an encryption expert to build a super computer to try to break the encryption by brute force, at a price.
|
125 |
|
126 |
= My site was hacked, and I have no backups! I thought UpdraftPlus was working! Can I kill you? =
|
127 |
|
128 |
No, there's no warranty or guarantee, etc. It's completely up to you to verify that UpdraftPlus is working correctly. If it doesn't then that's unfortunate, but this is a free plugin.
|
129 |
|
130 |
+
= Does UpdraftPlus delete all its settings when it is de-installed? =
|
131 |
+
|
132 |
+
No. Doing so is "cleaner", but some users also de-install and re-install and don't want to have to re-enter their settings. If you want to remove all UpdraftPlus's settings, then there's a button down at the bottom of the settings page.
|
133 |
+
|
134 |
= I am not running the most recent version of UpdraftPlus. Should I upgrade? =
|
135 |
|
136 |
Yes; especially before you submit any support requests.
|
141 |
|
142 |
== Changelog ==
|
143 |
|
144 |
+
= 1.3.14 - 01/26/2013 =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
* Various changes to Google Drive authentication to help those who don't enter the correct details first time, or who later need to change accounts.
|
146 |
|
147 |
= 1.3.12 - 01/25/2013 =
|
trunk/example-decrypt.php
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
|
5 |
+
To dump the decrypted file using the given key on stdout, call:
|
6 |
+
|
7 |
+
rijndael_decrypt_file( '../path/to/file.crypt' , 'mykey' );
|
8 |
+
|
9 |
+
Thus, here are the easy instructions:
|
10 |
+
|
11 |
+
1) Add a line like the above into this PHP file (not inside these comments, but outside)
|
12 |
+
e.g.
|
13 |
+
rijndael_decrypt_file( '/home/myself/myfile.crypt' , 'MYKEY' );
|
14 |
+
|
15 |
+
2) Run this file (and make sure that includes/Rijndael.php is available, if you are moving this file around)
|
16 |
+
e.g.
|
17 |
+
php /home/myself/example-decrypt.php >output.sql.gz
|
18 |
+
|
19 |
+
3) You may then want to gunzip the resulting file to have a standard SQL file.
|
20 |
+
e.g.
|
21 |
+
gunzip output.sql.gz
|
22 |
+
|
23 |
+
*/
|
24 |
+
|
25 |
+
function rijndael_decrypt_file($file, $key) {
|
26 |
+
|
27 |
+
require_once(dirname(__FILE__).'/includes/Rijndael.php');
|
28 |
+
|
29 |
+
$rijndael = new Crypt_Rijndael();
|
30 |
+
$rijndael->setKey($key);
|
31 |
+
$in_handle = fopen($file,'r');
|
32 |
+
$ciphertext = "";
|
33 |
+
while (!feof ($in_handle)) {
|
34 |
+
$ciphertext .= fread($in_handle, 16384);
|
35 |
+
}
|
36 |
+
fclose ($in_handle);
|
37 |
+
print $rijndael->decrypt($ciphertext);
|
38 |
+
|
39 |
+
}
|
40 |
+
|
41 |
+
?>
|
trunk/images/dropbox-logo.png
ADDED
Binary file
|
trunk/includes/Dropbox/API.php
ADDED
@@ -0,0 +1,583 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Dropbox API base class
|
5 |
+
* @author Ben Tadiar <ben@handcraftedbyben.co.uk>
|
6 |
+
* @link https://github.com/benthedesigner/dropbox
|
7 |
+
* @link https://www.dropbox.com/developers
|
8 |
+
* @link https://status.dropbox.com Dropbox status
|
9 |
+
* @package Dropbox
|
10 |
+
*/
|
11 |
+
class Dropbox_API
|
12 |
+
{
|
13 |
+
// API Endpoints
|
14 |
+
const API_URL = 'https://api.dropbox.com/1/';
|
15 |
+
const CONTENT_URL = 'https://api-content.dropbox.com/1/';
|
16 |
+
|
17 |
+
/**
|
18 |
+
* OAuth consumer object
|
19 |
+
* @var null|OAuth\Consumer
|
20 |
+
*/
|
21 |
+
private $OAuth;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* The root level for file paths
|
25 |
+
* Either `dropbox` or `sandbox` (preferred)
|
26 |
+
* @var null|string
|
27 |
+
*/
|
28 |
+
private $root;
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Format of the API response
|
32 |
+
* @var string
|
33 |
+
*/
|
34 |
+
private $responseFormat = 'php';
|
35 |
+
|
36 |
+
/**
|
37 |
+
* JSONP callback
|
38 |
+
* @var string
|
39 |
+
*/
|
40 |
+
private $callback = 'dropboxCallback';
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Chunk size used for chunked uploads
|
44 |
+
* @see \Dropbox\API::chunkedUpload()
|
45 |
+
*/
|
46 |
+
private $chunkSize = 4194304;
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Set the OAuth consumer object
|
50 |
+
* See 'General Notes' at the link below for information on access type
|
51 |
+
* @link https://www.dropbox.com/developers/reference/api
|
52 |
+
* @param OAuth\Consumer\ConsumerAbstract $OAuth
|
53 |
+
* @param string $root Dropbox app access type
|
54 |
+
*/
|
55 |
+
public function __construct(Dropbox_ConsumerAbstract $OAuth, $root = 'sandbox')
|
56 |
+
{
|
57 |
+
$this->OAuth = $OAuth;
|
58 |
+
$this->setRoot($root);
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Set the root level
|
63 |
+
* @param mixed $root
|
64 |
+
* @throws Exception
|
65 |
+
* @return void
|
66 |
+
*/
|
67 |
+
public function setRoot($root)
|
68 |
+
{
|
69 |
+
if ($root !== 'sandbox' && $root !== 'dropbox') {
|
70 |
+
throw new Exception("Expected a root of either 'dropbox' or 'sandbox', got '$root'");
|
71 |
+
} else {
|
72 |
+
$this->root = $root;
|
73 |
+
}
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Retrieves information about the user's account
|
78 |
+
* @return object stdClass
|
79 |
+
*/
|
80 |
+
public function accountInfo()
|
81 |
+
{
|
82 |
+
$response = $this->fetch('POST', self::API_URL, 'account/info');
|
83 |
+
return $response;
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Uploads a physical file from disk
|
88 |
+
* Dropbox impose a 150MB limit to files uploaded via the API. If the file
|
89 |
+
* exceeds this limit or does not exist, an Exception will be thrown
|
90 |
+
* @param string $file Absolute path to the file to be uploaded
|
91 |
+
* @param string|bool $filename The destination filename of the uploaded file
|
92 |
+
* @param string $path Path to upload the file to, relative to root
|
93 |
+
* @param boolean $overwrite Should the file be overwritten? (Default: true)
|
94 |
+
* @return object stdClass
|
95 |
+
*/
|
96 |
+
public function putFile($file, $filename = false, $path = '', $overwrite = true)
|
97 |
+
{
|
98 |
+
if (file_exists($file)) {
|
99 |
+
if (filesize($file) <= 157286400) {
|
100 |
+
$call = 'files/' . $this->root . '/' . $this->encodePath($path);
|
101 |
+
// If no filename is provided we'll use the original filename
|
102 |
+
$filename = (is_string($filename)) ? $filename : basename($file);
|
103 |
+
$params = array(
|
104 |
+
'filename' => $filename,
|
105 |
+
'file' => '@' . str_replace('\\', '/', $file) . ';filename=' . $filename,
|
106 |
+
'overwrite' => (int) $overwrite,
|
107 |
+
);
|
108 |
+
$response = $this->fetch('POST', self::CONTENT_URL, $call, $params);
|
109 |
+
return $response;
|
110 |
+
}
|
111 |
+
throw new Exception('File exceeds 150MB upload limit');
|
112 |
+
}
|
113 |
+
|
114 |
+
// Throw an Exception if the file does not exist
|
115 |
+
throw new Exception('Local file ' . $file . ' does not exist');
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Uploads file data from a stream
|
120 |
+
* Note: This function is experimental and requires further testing
|
121 |
+
* @todo Add filesize check
|
122 |
+
* @param resource $stream A readable stream created using fopen()
|
123 |
+
* @param string $filename The destination filename, including path
|
124 |
+
* @param boolean $overwrite Should the file be overwritten? (Default: true)
|
125 |
+
* @return array
|
126 |
+
*/
|
127 |
+
public function putStream($stream, $filename, $overwrite = true)
|
128 |
+
{
|
129 |
+
$this->OAuth->setInFile($stream);
|
130 |
+
$path = $this->encodePath($filename);
|
131 |
+
$call = 'files_put/' . $this->root . '/' . $path;
|
132 |
+
$params = array('overwrite' => (int) $overwrite);
|
133 |
+
$response = $this->fetch('PUT', self::CONTENT_URL, $call, $params);
|
134 |
+
return $response;
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Uploads large files to Dropbox in mulitple chunks
|
139 |
+
* @param string $file Absolute path to the file to be uploaded
|
140 |
+
* @param string|bool $filename The destination filename of the uploaded file
|
141 |
+
* @param string $path Path to upload the file to, relative to root
|
142 |
+
* @param boolean $overwrite Should the file be overwritten? (Default: true)
|
143 |
+
* @param integer $offset position to seek to when opening the file
|
144 |
+
* @param string $uploadID existing upload_id to resume an upload
|
145 |
+
* @param string|array function to call back to upon each chunk
|
146 |
+
* @return stdClass
|
147 |
+
*/
|
148 |
+
public function chunkedUpload($file, $filename = false, $path = '', $overwrite = true, $offset = 0, $uploadID = null, $callback = null)
|
149 |
+
{
|
150 |
+
if (file_exists($file)) {
|
151 |
+
if ($handle = @fopen($file, 'r')) {
|
152 |
+
// Set initial upload ID and offset
|
153 |
+
if ($offset > 0) {
|
154 |
+
fseek($handle, $offset);
|
155 |
+
}
|
156 |
+
|
157 |
+
// Read from the file handle until EOF, uploading each chunk
|
158 |
+
while ($data = fread($handle, $this->chunkSize)) {
|
159 |
+
// Open a temporary file handle and write a chunk of data to it
|
160 |
+
$chunkHandle = fopen('php://temp', 'rw');
|
161 |
+
fwrite($chunkHandle, $data);
|
162 |
+
|
163 |
+
// Set the file, request parameters and send the request
|
164 |
+
$this->OAuth->setInFile($chunkHandle);
|
165 |
+
$params = array('upload_id' => $uploadID, 'offset' => $offset);
|
166 |
+
$response = $this->fetch('PUT', self::CONTENT_URL, 'chunked_upload', $params);
|
167 |
+
|
168 |
+
// On subsequent chunks, use the upload ID returned by the previous request
|
169 |
+
if (isset($response['body']->upload_id)) {
|
170 |
+
$uploadID = $response['body']->upload_id;
|
171 |
+
}
|
172 |
+
|
173 |
+
if (isset($response['body']->offset)) {
|
174 |
+
$offset = $response['body']->offset;
|
175 |
+
if ($callback) {
|
176 |
+
call_user_func($callback, $offset, $uploadID);
|
177 |
+
}
|
178 |
+
}
|
179 |
+
|
180 |
+
// Close the file handle for this chunk
|
181 |
+
fclose($chunkHandle);
|
182 |
+
}
|
183 |
+
|
184 |
+
// Complete the chunked upload
|
185 |
+
$filename = (is_string($filename)) ? $filename : basename($file);
|
186 |
+
$call = 'commit_chunked_upload/' . $this->root . '/' . $this->encodePath($path . $filename);
|
187 |
+
$params = array('overwrite' => (int) $overwrite, 'upload_id' => $uploadID);
|
188 |
+
$response = $this->fetch('POST', self::CONTENT_URL, $call, $params);
|
189 |
+
return $response;
|
190 |
+
} else {
|
191 |
+
throw new Exception('Could not open ' . $file . ' for reading');
|
192 |
+
}
|
193 |
+
}
|
194 |
+
|
195 |
+
// Throw an Exception if the file does not exist
|
196 |
+
throw new Exception('Local file ' . $file . ' does not exist');
|
197 |
+
}
|
198 |
+
|
199 |
+
/**
|
200 |
+
* Downloads a file
|
201 |
+
* Returns the base filename, raw file data and mime type returned by Fileinfo
|
202 |
+
* @param string $file Path to file, relative to root, including path
|
203 |
+
* @param string $outFile Filename to write the downloaded file to
|
204 |
+
* @param string $revision The revision of the file to retrieve
|
205 |
+
* @return array
|
206 |
+
*/
|
207 |
+
public function getFile($file, $outFile = false, $revision = null)
|
208 |
+
{
|
209 |
+
// Only allow php response format for this call
|
210 |
+
if ($this->responseFormat !== 'php') {
|
211 |
+
throw new Exception('This method only supports the `php` response format');
|
212 |
+
}
|
213 |
+
|
214 |
+
$handle = null;
|
215 |
+
if ($outFile !== false) {
|
216 |
+
// Create a file handle if $outFile is specified
|
217 |
+
if (!$handle = fopen($outFile, 'w')) {
|
218 |
+
throw new Exception("Unable to open file handle for $outFile");
|
219 |
+
} else {
|
220 |
+
$this->OAuth->setOutFile($handle);
|
221 |
+
}
|
222 |
+
}
|
223 |
+
|
224 |
+
$file = $this->encodePath($file);
|
225 |
+
$call = 'files/' . $this->root . '/' . $file;
|
226 |
+
$params = array('rev' => $revision);
|
227 |
+
$response = $this->fetch('GET', self::CONTENT_URL, $call, $params);
|
228 |
+
|
229 |
+
// Close the file handle if one was opened
|
230 |
+
if ($handle) fclose($handle);
|
231 |
+
|
232 |
+
return array(
|
233 |
+
'name' => ($outFile) ? $outFile : basename($file),
|
234 |
+
'mime' => $this->getMimeType(($outFile) ? $outFile : $response['body'], $outFile),
|
235 |
+
'meta' => json_decode($response['headers']['x-dropbox-metadata']),
|
236 |
+
'data' => $response['body'],
|
237 |
+
);
|
238 |
+
}
|
239 |
+
|
240 |
+
/**
|
241 |
+
* Retrieves file and folder metadata
|
242 |
+
* @param string $path The path to the file/folder, relative to root
|
243 |
+
* @param string $rev Return metadata for a specific revision (Default: latest rev)
|
244 |
+
* @param int $limit Maximum number of listings to return
|
245 |
+
* @param string $hash Metadata hash to compare against
|
246 |
+
* @param bool $list Return contents field with response
|
247 |
+
* @param bool $deleted Include files/folders that have been deleted
|
248 |
+
* @return object stdClass
|
249 |
+
*/
|
250 |
+
public function metaData($path = null, $rev = null, $limit = 10000, $hash = false, $list = true, $deleted = false)
|
251 |
+
{
|
252 |
+
$call = 'metadata/' . $this->root . '/' . $this->encodePath($path);
|
253 |
+
$params = array(
|
254 |
+
'file_limit' => ($limit < 1) ? 1 : (($limit > 10000) ? 10000 : (int) $limit),
|
255 |
+
'hash' => (is_string($hash)) ? $hash : 0,
|
256 |
+
'list' => (int) $list,
|
257 |
+
'include_deleted' => (int) $deleted,
|
258 |
+
'rev' => (is_string($rev)) ? $rev : null,
|
259 |
+
);
|
260 |
+
$response = $this->fetch('POST', self::API_URL, $call, $params);
|
261 |
+
return $response;
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* Return "delta entries", intructing you how to update
|
266 |
+
* your application state to match the server's state
|
267 |
+
* Important: This method does not make changes to the application state
|
268 |
+
* @param null|string $cursor Used to keep track of your current state
|
269 |
+
* @return array Array of delta entries
|
270 |
+
*/
|
271 |
+
public function delta($cursor = null)
|
272 |
+
{
|
273 |
+
$call = 'delta';
|
274 |
+
$params = array('cursor' => $cursor);
|
275 |
+
$response = $this->fetch('POST', self::API_URL, $call, $params);
|
276 |
+
return $response;
|
277 |
+
}
|
278 |
+
|
279 |
+
/**
|
280 |
+
* Obtains metadata for the previous revisions of a file
|
281 |
+
* @param string Path to the file, relative to root
|
282 |
+
* @param integer Number of revisions to return (1-1000)
|
283 |
+
* @return array
|
284 |
+
*/
|
285 |
+
public function revisions($file, $limit = 10)
|
286 |
+
{
|
287 |
+
$call = 'revisions/' . $this->root . '/' . $this->encodePath($file);
|
288 |
+
$params = array(
|
289 |
+
'rev_limit' => ($limit < 1) ? 1 : (($limit > 1000) ? 1000 : (int) $limit),
|
290 |
+
);
|
291 |
+
$response = $this->fetch('GET', self::API_URL, $call, $params);
|
292 |
+
return $response;
|
293 |
+
}
|
294 |
+
|
295 |
+
/**
|
296 |
+
* Restores a file path to a previous revision
|
297 |
+
* @param string $file Path to the file, relative to root
|
298 |
+
* @param string $revision The revision of the file to restore
|
299 |
+
* @return object stdClass
|
300 |
+
*/
|
301 |
+
public function restore($file, $revision)
|
302 |
+
{
|
303 |
+
$call = 'restore/' . $this->root . '/' . $this->encodePath($file);
|
304 |
+
$params = array('rev' => $revision);
|
305 |
+
$response = $this->fetch('POST', self::API_URL, $call, $params);
|
306 |
+
return $response;
|
307 |
+
}
|
308 |
+
|
309 |
+
/**
|
310 |
+
* Returns metadata for all files and folders that match the search query
|
311 |
+
* @param mixed $query The search string. Must be at least 3 characters long
|
312 |
+
* @param string $path The path to the folder you want to search in
|
313 |
+
* @param integer $limit Maximum number of results to return (1-1000)
|
314 |
+
* @param boolean $deleted Include deleted files/folders in the search
|
315 |
+
* @return array
|
316 |
+
*/
|
317 |
+
public function search($query, $path = '', $limit = 1000, $deleted = false)
|
318 |
+
{
|
319 |
+
$call = 'search/' . $this->root . '/' . $this->encodePath($path);
|
320 |
+
$params = array(
|
321 |
+
'query' => $query,
|
322 |
+
'file_limit' => ($limit < 1) ? 1 : (($limit > 1000) ? 1000 : (int) $limit),
|
323 |
+
'include_deleted' => (int) $deleted,
|
324 |
+
);
|
325 |
+
$response = $this->fetch('GET', self::API_URL, $call, $params);
|
326 |
+
return $response;
|
327 |
+
}
|
328 |
+
|
329 |
+
/**
|
330 |
+
* Creates and returns a shareable link to files or folders
|
331 |
+
* The link returned is for a preview page from which the user an choose to
|
332 |
+
* download the file if they wish. For direct download links, see media().
|
333 |
+
* @param string $path The path to the file/folder you want a sharable link to
|
334 |
+
* @return object stdClass
|
335 |
+
*/
|
336 |
+
public function shares($path, $shortUrl = true)
|
337 |
+
{
|
338 |
+
$call = 'shares/' . $this->root . '/' .$this->encodePath($path);
|
339 |
+
$params = array('short_url' => ($shortUrl) ? 1 : 0);
|
340 |
+
$response = $this->fetch('POST', self::API_URL, $call, $params);
|
341 |
+
return $response;
|
342 |
+
}
|
343 |
+
|
344 |
+
/**
|
345 |
+
* Returns a link directly to a file
|
346 |
+
* @param string $path The path to the media file you want a direct link to
|
347 |
+
* @return object stdClass
|
348 |
+
*/
|
349 |
+
public function media($path)
|
350 |
+
{
|
351 |
+
$call = 'media/' . $this->root . '/' . $this->encodePath($path);
|
352 |
+
$response = $this->fetch('POST', self::API_URL, $call);
|
353 |
+
return $response;
|
354 |
+
}
|
355 |
+
|
356 |
+
/**
|
357 |
+
* Gets a thumbnail for an image
|
358 |
+
* @param string $file The path to the image you wish to thumbnail
|
359 |
+
* @param string $format The thumbnail format, either JPEG or PNG
|
360 |
+
* @param string $size The size of the thumbnail
|
361 |
+
* @return array
|
362 |
+
*/
|
363 |
+
public function thumbnails($file, $format = 'JPEG', $size = 'small')
|
364 |
+
{
|
365 |
+
// Only allow php response format for this call
|
366 |
+
if ($this->responseFormat !== 'php') {
|
367 |
+
throw new Exception('This method only supports the `php` response format');
|
368 |
+
}
|
369 |
+
|
370 |
+
$format = strtoupper($format);
|
371 |
+
// If $format is not 'PNG', default to 'JPEG'
|
372 |
+
if ($format != 'PNG') $format = 'JPEG';
|
373 |
+
|
374 |
+
$size = strtolower($size);
|
375 |
+
$sizes = array('s', 'm', 'l', 'xl', 'small', 'medium', 'large');
|
376 |
+
// If $size is not valid, default to 'small'
|
377 |
+
if (!in_array($size, $sizes)) $size = 'small';
|
378 |
+
|
379 |
+
$call = 'thumbnails/' . $this->root . '/' . $this->encodePath($file);
|
380 |
+
$params = array('format' => $format, 'size' => $size);
|
381 |
+
$response = $this->fetch('GET', self::CONTENT_URL, $call, $params);
|
382 |
+
|
383 |
+
return array(
|
384 |
+
'name' => basename($file),
|
385 |
+
'mime' => $this->getMimeType($response['body']),
|
386 |
+
'meta' => json_decode($response['headers']['x-dropbox-metadata']),
|
387 |
+
'data' => $response['body'],
|
388 |
+
);
|
389 |
+
}
|
390 |
+
|
391 |
+
/**
|
392 |
+
* Creates and returns a copy_ref to a file
|
393 |
+
* This reference string can be used to copy that file to another user's
|
394 |
+
* Dropbox by passing it in as the from_copy_ref parameter on /fileops/copy
|
395 |
+
* @param $path File for which ref should be created, relative to root
|
396 |
+
* @return array
|
397 |
+
*/
|
398 |
+
public function copyRef($path)
|
399 |
+
{
|
400 |
+
$call = 'copy_ref/' . $this->root . '/' . $this->encodePath($path);
|
401 |
+
$response = $this->fetch('GET', self::API_URL, $call);
|
402 |
+
return $response;
|
403 |
+
}
|
404 |
+
|
405 |
+
/**
|
406 |
+
* Copies a file or folder to a new location
|
407 |
+
* @param string $from File or folder to be copied, relative to root
|
408 |
+
* @param string $to Destination path, relative to root
|
409 |
+
* @param null|string $fromCopyRef Must be used instead of the from_path
|
410 |
+
* @return object stdClass
|
411 |
+
*/
|
412 |
+
public function copy($from, $to, $fromCopyRef = null)
|
413 |
+
{
|
414 |
+
$call = 'fileops/copy';
|
415 |
+
$params = array(
|
416 |
+
'root' => $this->root,
|
417 |
+
'from_path' => $this->normalisePath($from),
|
418 |
+
'to_path' => $this->normalisePath($to),
|
419 |
+
);
|
420 |
+
|
421 |
+
if ($fromCopyRef) {
|
422 |
+
$params['from_path'] = null;
|
423 |
+
$params['from_copy_ref'] = $fromCopyRef;
|
424 |
+
}
|
425 |
+
|
426 |
+
$response = $this->fetch('POST', self::API_URL, $call, $params);
|
427 |
+
return $response;
|
428 |
+
}
|
429 |
+
|
430 |
+
/**
|
431 |
+
* Creates a folder
|
432 |
+
* @param string New folder to create relative to root
|
433 |
+
* @return object stdClass
|
434 |
+
*/
|
435 |
+
public function create($path)
|
436 |
+
{
|
437 |
+
$call = 'fileops/create_folder';
|
438 |
+
$params = array('root' => $this->root, 'path' => $this->normalisePath($path));
|
439 |
+
$response = $this->fetch('POST', self::API_URL, $call, $params);
|
440 |
+
return $response;
|
441 |
+
}
|
442 |
+
|
443 |
+
/**
|
444 |
+
* Deletes a file or folder
|
445 |
+
* @param string $path The path to the file or folder to be deleted
|
446 |
+
* @return object stdClass
|
447 |
+
*/
|
448 |
+
public function delete($path)
|
449 |
+
{
|
450 |
+
$call = 'fileops/delete';
|
451 |
+
$params = array('root' => $this->root, 'path' => $this->normalisePath($path));
|
452 |
+
$response = $this->fetch('POST', self::API_URL, $call, $params);
|
453 |
+
return $response;
|
454 |
+
}
|
455 |
+
|
456 |
+
/**
|
457 |
+
* Moves a file or folder to a new location
|
458 |
+
* @param string $from File or folder to be moved, relative to root
|
459 |
+
* @param string $to Destination path, relative to root
|
460 |
+
* @return object stdClass
|
461 |
+
*/
|
462 |
+
public function move($from, $to)
|
463 |
+
{
|
464 |
+
$call = 'fileops/move';
|
465 |
+
$params = array(
|
466 |
+
'root' => $this->root,
|
467 |
+
'from_path' => $this->normalisePath($from),
|
468 |
+
'to_path' => $this->normalisePath($to),
|
469 |
+
);
|
470 |
+
$response = $this->fetch('POST', self::API_URL, $call, $params);
|
471 |
+
return $response;
|
472 |
+
}
|
473 |
+
|
474 |
+
/**
|
475 |
+
* Intermediate fetch function
|
476 |
+
* @param string $method The HTTP method
|
477 |
+
* @param string $url The API endpoint
|
478 |
+
* @param string $call The API method to call
|
479 |
+
* @param array $params Additional parameters
|
480 |
+
* @return mixed
|
481 |
+
*/
|
482 |
+
private function fetch($method, $url, $call, array $params = array())
|
483 |
+
{
|
484 |
+
// Make the API call via the consumer
|
485 |
+
$response = $this->OAuth->fetch($method, $url, $call, $params);
|
486 |
+
|
487 |
+
// Format the response and return
|
488 |
+
switch ($this->responseFormat) {
|
489 |
+
case 'json':
|
490 |
+
return json_encode($response);
|
491 |
+
case 'jsonp':
|
492 |
+
$response = json_encode($response);
|
493 |
+
return $this->callback . '(' . $response . ')';
|
494 |
+
default:
|
495 |
+
return $response;
|
496 |
+
}
|
497 |
+
}
|
498 |
+
|
499 |
+
/**
|
500 |
+
* Set the API response format
|
501 |
+
* @param string $format One of php, json or jsonp
|
502 |
+
* @return void
|
503 |
+
*/
|
504 |
+
public function setResponseFormat($format)
|
505 |
+
{
|
506 |
+
$format = strtolower($format);
|
507 |
+
if (!in_array($format, array('php', 'json', 'jsonp'))) {
|
508 |
+
throw new Exception("Expected a format of php, json or jsonp, got '$format'");
|
509 |
+
} else {
|
510 |
+
$this->responseFormat = $format;
|
511 |
+
}
|
512 |
+
}
|
513 |
+
|
514 |
+
/**
|
515 |
+
* Set the chunk size for chunked uploads
|
516 |
+
* If $chunkSize is empty, set to 4194304 bytes (4 MB)
|
517 |
+
* @see \Dropbox\API\chunkedUpload()
|
518 |
+
*/
|
519 |
+
public function setChunkSize($chunkSize = 4194304)
|
520 |
+
{
|
521 |
+
if (!is_int($chunkSize)) {
|
522 |
+
throw new Exception('Expecting chunk size to be an integer, got ' . gettype($chunkSize));
|
523 |
+
} elseif ($chunkSize > 157286400) {
|
524 |
+
throw new Exception('Chunk size must not exceed 157286400 bytes, got ' . $chunkSize);
|
525 |
+
} else {
|
526 |
+
$this->chunkSize = $chunkSize;
|
527 |
+
}
|
528 |
+
}
|
529 |
+
|
530 |
+
/**
|
531 |
+
* Set the JSONP callback function
|
532 |
+
* @param string $function
|
533 |
+
* @return void
|
534 |
+
*/
|
535 |
+
public function setCallback($function)
|
536 |
+
{
|
537 |
+
$this->callback = $function;
|
538 |
+
}
|
539 |
+
|
540 |
+
/**
|
541 |
+
* Get the mime type of downloaded file
|
542 |
+
* If the Fileinfo extension is not loaded, return false
|
543 |
+
* @param string $data File contents as a string or filename
|
544 |
+
* @param string $isFilename Is $data a filename?
|
545 |
+
* @return boolean|string Mime type and encoding of the file
|
546 |
+
*/
|
547 |
+
private function getMimeType($data, $isFilename = false)
|
548 |
+
{
|
549 |
+
if (extension_loaded('fileinfo')) {
|
550 |
+
$finfo = new \finfo(FILEINFO_MIME);
|
551 |
+
if ($isFilename !== false) {
|
552 |
+
return $finfo->file($data);
|
553 |
+
}
|
554 |
+
return $finfo->buffer($data);
|
555 |
+
}
|
556 |
+
return false;
|
557 |
+
}
|
558 |
+
|
559 |
+
/**
|
560 |
+
* Trim the path of forward slashes and replace
|
561 |
+
* consecutive forward slashes with a single slash
|
562 |
+
* @param string $path The path to normalise
|
563 |
+
* @return string
|
564 |
+
*/
|
565 |
+
private function normalisePath($path)
|
566 |
+
{
|
567 |
+
$path = preg_replace('#/+#', '/', trim($path, '/'));
|
568 |
+
return $path;
|
569 |
+
}
|
570 |
+
|
571 |
+
/**
|
572 |
+
* Encode the path, then replace encoded slashes
|
573 |
+
* with literal forward slash characters
|
574 |
+
* @param string $path The path to encode
|
575 |
+
* @return string
|
576 |
+
*/
|
577 |
+
private function encodePath($path)
|
578 |
+
{
|
579 |
+
$path = $this->normalisePath($path);
|
580 |
+
$path = str_replace('%2F', '/', rawurlencode($path));
|
581 |
+
return $path;
|
582 |
+
}
|
583 |
+
}
|
trunk/includes/Dropbox/Exception.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Dropbox Exception class
|
5 |
+
* @author Ben Tadiar <ben@handcraftedbyben.co.uk>
|
6 |
+
* @link https://github.com/benthedesigner/dropbox
|
7 |
+
* @package Dropbox
|
8 |
+
*/
|
9 |
+
class Dropbox_Exception extends Exception
|
10 |
+
{
|
11 |
+
|
12 |
+
}
|
trunk/includes/Dropbox/OAuth/Consumer/ConsumerAbstract.php
ADDED
@@ -0,0 +1,307 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Abstract OAuth consumer
|
5 |
+
* @author Ben Tadiar <ben@handcraftedbyben.co.uk>
|
6 |
+
* @link https://github.com/benthedesigner/dropbox
|
7 |
+
* @package Dropbox\OAuth
|
8 |
+
* @subpackage Consumer
|
9 |
+
*/
|
10 |
+
|
11 |
+
abstract class Dropbox_ConsumerAbstract
|
12 |
+
{
|
13 |
+
// Dropbox web endpoint
|
14 |
+
const WEB_URL = 'https://www.dropbox.com/1/';
|
15 |
+
|
16 |
+
// OAuth flow methods
|
17 |
+
const REQUEST_TOKEN_METHOD = 'oauth/request_token';
|
18 |
+
const AUTHORISE_METHOD = 'oauth/authorize';
|
19 |
+
const ACCESS_TOKEN_METHOD = 'oauth/access_token';
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Signature method, either PLAINTEXT or HMAC-SHA1
|
23 |
+
* @var string
|
24 |
+
*/
|
25 |
+
private $sigMethod = 'PLAINTEXT';
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Output file handle
|
29 |
+
* @var null|resource
|
30 |
+
*/
|
31 |
+
protected $outFile = null;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Input file handle
|
35 |
+
* @var null|resource
|
36 |
+
*/
|
37 |
+
protected $inFile = null;
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Authenticate using 3-legged OAuth flow, firstly
|
41 |
+
* checking we don't already have tokens to use
|
42 |
+
* @return void
|
43 |
+
*/
|
44 |
+
protected function authenticate()
|
45 |
+
{
|
46 |
+
if ((!$this->storage->get('access_token'))) {
|
47 |
+
try {
|
48 |
+
$this->getAccessToken();
|
49 |
+
} catch(Dropbox_Exception $e) {
|
50 |
+
$this->getRequestToken();
|
51 |
+
$this->authorise();
|
52 |
+
}
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Acquire an unauthorised request token
|
58 |
+
* @link http://tools.ietf.org/html/rfc5849#section-2.1
|
59 |
+
* @return void
|
60 |
+
*/
|
61 |
+
private function getRequestToken()
|
62 |
+
{
|
63 |
+
// Nullify any request token we already have
|
64 |
+
$this->storage->set(null, 'request_token');
|
65 |
+
$url = Dropbox_API::API_URL . self::REQUEST_TOKEN_METHOD;
|
66 |
+
$response = $this->fetch('POST', $url, '');
|
67 |
+
$token = $this->parseTokenString($response['body']);
|
68 |
+
$this->storage->set($token, 'request_token');
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Obtain user authorisation
|
73 |
+
* The user will be redirected to Dropbox' web endpoint
|
74 |
+
* @link http://tools.ietf.org/html/rfc5849#section-2.2
|
75 |
+
* @return void
|
76 |
+
*/
|
77 |
+
private function authorise()
|
78 |
+
{
|
79 |
+
// Only redirect if using CLI
|
80 |
+
if (PHP_SAPI !== 'cli') {
|
81 |
+
$url = $this->getAuthoriseUrl();
|
82 |
+
header('Location: ' . $url);
|
83 |
+
exit;
|
84 |
+
}
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Build the user authorisation URL
|
89 |
+
* @return string
|
90 |
+
*/
|
91 |
+
public function getAuthoriseUrl()
|
92 |
+
{
|
93 |
+
// Get the request token
|
94 |
+
$token = $this->getToken();
|
95 |
+
|
96 |
+
// Prepare request parameters
|
97 |
+
$params = array(
|
98 |
+
'oauth_token' => $token->oauth_token,
|
99 |
+
'oauth_token_secret' => $token->oauth_token_secret,
|
100 |
+
'oauth_callback' => $this->callback,
|
101 |
+
);
|
102 |
+
|
103 |
+
// Build the URL and redirect the user
|
104 |
+
$query = '?' . http_build_query($params, '', '&');
|
105 |
+
$url = self::WEB_URL . self::AUTHORISE_METHOD . $query;
|
106 |
+
return $url;
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Acquire an access token
|
111 |
+
* Tokens acquired at this point should be stored to
|
112 |
+
* prevent having to request new tokens for each API call
|
113 |
+
* @link http://tools.ietf.org/html/rfc5849#section-2.3
|
114 |
+
*/
|
115 |
+
public function getAccessToken()
|
116 |
+
{
|
117 |
+
// Get the signed request URL
|
118 |
+
$response = $this->fetch('POST', Dropbox_API::API_URL, self::ACCESS_TOKEN_METHOD);
|
119 |
+
$token = $this->parseTokenString($response['body']);
|
120 |
+
$this->storage->set($token, 'access_token');
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Get the request/access token
|
125 |
+
* This will return the access/request token depending on
|
126 |
+
* which stage we are at in the OAuth flow, or a dummy object
|
127 |
+
* if we have not yet started the authentication process
|
128 |
+
* @return object stdClass
|
129 |
+
*/
|
130 |
+
private function getToken()
|
131 |
+
{
|
132 |
+
if (!$token = $this->storage->get('access_token')) {
|
133 |
+
if (!$token = $this->storage->get('request_token')) {
|
134 |
+
$token = new \stdClass();
|
135 |
+
$token->oauth_token = null;
|
136 |
+
$token->oauth_token_secret = null;
|
137 |
+
}
|
138 |
+
}
|
139 |
+
return $token;
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Generate signed request URL
|
144 |
+
* See inline comments for description
|
145 |
+
* @link http://tools.ietf.org/html/rfc5849#section-3.4
|
146 |
+
* @param string $method HTTP request method
|
147 |
+
* @param string $url API endpoint to send the request to
|
148 |
+
* @param string $call API call to send
|
149 |
+
* @param array $additional Additional parameters as an associative array
|
150 |
+
* @return array
|
151 |
+
*/
|
152 |
+
protected function getSignedRequest($method, $url, $call, array $additional = array())
|
153 |
+
{
|
154 |
+
// Get the request/access token
|
155 |
+
$token = $this->getToken();
|
156 |
+
|
157 |
+
// Generate a random string for the request
|
158 |
+
$nonce = md5(microtime(true) . uniqid('', true));
|
159 |
+
|
160 |
+
// Prepare the standard request parameters
|
161 |
+
$params = array(
|
162 |
+
'oauth_consumer_key' => $this->consumerKey,
|
163 |
+
'oauth_token' => $token->oauth_token,
|
164 |
+
'oauth_signature_method' => $this->sigMethod,
|
165 |
+
'oauth_version' => '1.0',
|
166 |
+
// Generate nonce and timestamp if signature method is HMAC-SHA1
|
167 |
+
'oauth_timestamp' => ($this->sigMethod == 'HMAC-SHA1') ? time() : null,
|
168 |
+
'oauth_nonce' => ($this->sigMethod == 'HMAC-SHA1') ? $nonce : null,
|
169 |
+
);
|
170 |
+
|
171 |
+
// Merge with the additional request parameters
|
172 |
+
$params = array_merge($params, $additional);
|
173 |
+
ksort($params);
|
174 |
+
|
175 |
+
// URL encode each parameter to RFC3986 for use in the base string
|
176 |
+
$encoded = array();
|
177 |
+
foreach($params as $param => $value) {
|
178 |
+
if ($value !== null) {
|
179 |
+
// If the value is a file upload (prefixed with @), replace it with
|
180 |
+
// the destination filename, the file path will be sent in POSTFIELDS
|
181 |
+
if (isset($value[0]) && $value[0] === '@') $value = $params['filename'];
|
182 |
+
$encoded[] = $this->encode($param) . '=' . $this->encode($value);
|
183 |
+
} else {
|
184 |
+
unset($params[$param]);
|
185 |
+
}
|
186 |
+
}
|
187 |
+
|
188 |
+
// Build the first part of the string
|
189 |
+
$base = $method . '&' . $this->encode($url . $call) . '&';
|
190 |
+
|
191 |
+
// Re-encode the encoded parameter string and append to $base
|
192 |
+
$base .= $this->encode(implode('&', $encoded));
|
193 |
+
|
194 |
+
// Concatenate the secrets with an ampersand
|
195 |
+
$key = $this->consumerSecret . '&' . $token->oauth_token_secret;
|
196 |
+
|
197 |
+
// Get the signature string based on signature method
|
198 |
+
$signature = $this->getSignature($base, $key);
|
199 |
+
$params['oauth_signature'] = $signature;
|
200 |
+
|
201 |
+
// Build the signed request URL
|
202 |
+
$query = '?' . http_build_query($params, '', '&');
|
203 |
+
|
204 |
+
return array(
|
205 |
+
'url' => $url . $call . $query,
|
206 |
+
'postfields' => $params,
|
207 |
+
);
|
208 |
+
}
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Generate the oauth_signature for a request
|
212 |
+
* @param string $base Signature base string, used by HMAC-SHA1
|
213 |
+
* @param string $key Concatenated consumer and token secrets
|
214 |
+
*/
|
215 |
+
private function getSignature($base, $key)
|
216 |
+
{
|
217 |
+
switch ($this->sigMethod) {
|
218 |
+
case 'PLAINTEXT':
|
219 |
+
$signature = $key;
|
220 |
+
break;
|
221 |
+
case 'HMAC-SHA1':
|
222 |
+
$signature = base64_encode(hash_hmac('sha1', $base, $key, true));
|
223 |
+
break;
|
224 |
+
}
|
225 |
+
|
226 |
+
return $signature;
|
227 |
+
}
|
228 |
+
|
229 |
+
/**
|
230 |
+
* Set the OAuth signature method
|
231 |
+
* @param string $method Either PLAINTEXT or HMAC-SHA1
|
232 |
+
* @return void
|
233 |
+
*/
|
234 |
+
public function setSignatureMethod($method)
|
235 |
+
{
|
236 |
+
$method = strtoupper($method);
|
237 |
+
|
238 |
+
switch ($method) {
|
239 |
+
case 'PLAINTEXT':
|
240 |
+
case 'HMAC-SHA1':
|
241 |
+
$this->sigMethod = $method;
|
242 |
+
break;
|
243 |
+
default:
|
244 |
+
throw new Dropbox_Exception('Unsupported signature method ' . $method);
|
245 |
+
}
|
246 |
+
}
|
247 |
+
|
248 |
+
/**
|
249 |
+
* Set the output file
|
250 |
+
* @param resource Resource to stream response data to
|
251 |
+
* @return void
|
252 |
+
*/
|
253 |
+
public function setOutFile($handle)
|
254 |
+
{
|
255 |
+
if (!is_resource($handle) || get_resource_type($handle) != 'stream') {
|
256 |
+
throw new Dropbox_Exception('Outfile must be a stream resource');
|
257 |
+
}
|
258 |
+
$this->outFile = $handle;
|
259 |
+
}
|
260 |
+
|
261 |
+
/**
|
262 |
+
* Set the input file
|
263 |
+
* @param resource Resource to read data from
|
264 |
+
* @return void
|
265 |
+
*/
|
266 |
+
public function setInFile($handle)
|
267 |
+
{
|
268 |
+
if (!is_resource($handle) || get_resource_type($handle) != 'stream') {
|
269 |
+
throw new Dropbox_Exception('Infile must be a stream resource');
|
270 |
+
}
|
271 |
+
fseek($handle, 0);
|
272 |
+
$this->inFile = $handle;
|
273 |
+
}
|
274 |
+
|
275 |
+
/**
|
276 |
+
* Parse response parameters for a token into an object
|
277 |
+
* Dropbox returns tokens in the response parameters, and
|
278 |
+
* not a JSON encoded object as per other API requests
|
279 |
+
* @link http://oauth.net/core/1.0/#response_parameters
|
280 |
+
* @param string $response
|
281 |
+
* @return object stdClass
|
282 |
+
*/
|
283 |
+
private function parseTokenString($response)
|
284 |
+
{
|
285 |
+
$parts = explode('&', $response);
|
286 |
+
$token = new \stdClass();
|
287 |
+
foreach ($parts as $part) {
|
288 |
+
list($k, $v) = explode('=', $part, 2);
|
289 |
+
$k = strtolower($k);
|
290 |
+
$token->$k = $v;
|
291 |
+
}
|
292 |
+
return $token;
|
293 |
+
}
|
294 |
+
|
295 |
+
/**
|
296 |
+
* Encode a value to RFC3986
|
297 |
+
* This is a convenience method to decode ~ symbols encoded
|
298 |
+
* by rawurldecode. This will encode all characters except
|
299 |
+
* the unreserved set, ALPHA, DIGIT, '-', '.', '_', '~'
|
300 |
+
* @link http://tools.ietf.org/html/rfc5849#section-3.6
|
301 |
+
* @param mixed $value
|
302 |
+
*/
|
303 |
+
private function encode($value)
|
304 |
+
{
|
305 |
+
return str_replace('%7E', '~', rawurlencode($value));
|
306 |
+
}
|
307 |
+
}
|
trunk/includes/Dropbox/OAuth/Consumer/Curl.php
ADDED
@@ -0,0 +1,148 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* OAuth consumer using PHP cURL
|
5 |
+
* @author Ben Tadiar <ben@handcraftedbyben.co.uk>
|
6 |
+
* @link https://github.com/benthedesigner/dropbox
|
7 |
+
* @package Dropbox\OAuth
|
8 |
+
* @subpackage Consumer
|
9 |
+
*/
|
10 |
+
|
11 |
+
class Dropbox_Curl extends Dropbox_ConsumerAbstract
|
12 |
+
{
|
13 |
+
/**
|
14 |
+
* Default cURL options
|
15 |
+
* @var array
|
16 |
+
*/
|
17 |
+
private $defaultOptions = array(
|
18 |
+
CURLOPT_SSL_VERIFYPEER => true,
|
19 |
+
CURLOPT_VERBOSE => true,
|
20 |
+
CURLOPT_HEADER => true,
|
21 |
+
CURLINFO_HEADER_OUT => false,
|
22 |
+
CURLOPT_RETURNTRANSFER => true,
|
23 |
+
CURLOPT_FOLLOWLOCATION => false,
|
24 |
+
);
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Set properties and begin authentication
|
28 |
+
* @param string $key
|
29 |
+
* @param string $secret
|
30 |
+
* @param \Dropbox\OAuth\Consumer\StorageInterface $storage
|
31 |
+
* @param string $callback
|
32 |
+
*/
|
33 |
+
public function __construct($key, $secret, Dropbox_StorageInterface $storage, $callback = null)
|
34 |
+
{
|
35 |
+
// Check the cURL extension is loaded
|
36 |
+
if (!extension_loaded('curl')) {
|
37 |
+
throw new Dropbox_Exception('The cURL OAuth consumer requires the cURL extension');
|
38 |
+
}
|
39 |
+
|
40 |
+
$this->consumerKey = $key;
|
41 |
+
$this->consumerSecret = $secret;
|
42 |
+
$this->storage = $storage;
|
43 |
+
$this->callback = $callback;
|
44 |
+
$this->authenticate();
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Execute an API call
|
49 |
+
* @todo Improve error handling
|
50 |
+
* @param string $method The HTTP method
|
51 |
+
* @param string $url The API endpoint
|
52 |
+
* @param string $call The API method to call
|
53 |
+
* @param array $additional Additional parameters
|
54 |
+
* @return string|object stdClass
|
55 |
+
*/
|
56 |
+
public function fetch($method, $url, $call, array $additional = array())
|
57 |
+
{
|
58 |
+
// Get the signed request URL
|
59 |
+
$request = $this->getSignedRequest($method, $url, $call, $additional);
|
60 |
+
|
61 |
+
// Initialise and execute a cURL request
|
62 |
+
$handle = curl_init($request['url']);
|
63 |
+
|
64 |
+
// Get the default options array
|
65 |
+
$options = $this->defaultOptions;
|
66 |
+
$options[CURLOPT_CAINFO] = dirname(__FILE__) . '/ca-bundle.pem';
|
67 |
+
|
68 |
+
if ($method == 'GET' && $this->outFile) { // GET
|
69 |
+
$options[CURLOPT_RETURNTRANSFER] = false;
|
70 |
+
$options[CURLOPT_HEADER] = false;
|
71 |
+
$options[CURLOPT_FILE] = $this->outFile;
|
72 |
+
$options[CURLOPT_BINARYTRANSFER] = true;
|
73 |
+
$this->outFile = null;
|
74 |
+
} elseif ($method == 'POST') { // POST
|
75 |
+
$options[CURLOPT_POST] = true;
|
76 |
+
$options[CURLOPT_POSTFIELDS] = $request['postfields'];
|
77 |
+
} elseif ($method == 'PUT' && $this->inFile) { // PUT
|
78 |
+
$options[CURLOPT_PUT] = true;
|
79 |
+
$options[CURLOPT_INFILE] = $this->inFile;
|
80 |
+
// @todo Update so the data is not loaded into memory to get its size
|
81 |
+
$options[CURLOPT_INFILESIZE] = strlen(stream_get_contents($this->inFile));
|
82 |
+
fseek($this->inFile, 0);
|
83 |
+
$this->inFile = null;
|
84 |
+
}
|
85 |
+
|
86 |
+
// Set the cURL options at once
|
87 |
+
curl_setopt_array($handle, $options);
|
88 |
+
|
89 |
+
// Execute and parse the response
|
90 |
+
$response = curl_exec($handle);
|
91 |
+
curl_close($handle);
|
92 |
+
|
93 |
+
// Parse the response if it is a string
|
94 |
+
if (is_string($response)) {
|
95 |
+
$response = $this->parse($response);
|
96 |
+
}
|
97 |
+
|
98 |
+
// Check if an error occurred and throw an Exception
|
99 |
+
if (!empty($response['body']->error)) {
|
100 |
+
$message = $response['body']->error . ' (Status Code: ' . $response['code'] . ')';
|
101 |
+
throw new Dropbox_Exception($message);
|
102 |
+
}
|
103 |
+
|
104 |
+
return $response;
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Parse a cURL response
|
109 |
+
* @param string $response
|
110 |
+
* @return array
|
111 |
+
*/
|
112 |
+
private function parse($response)
|
113 |
+
{
|
114 |
+
// Explode the response into headers and body parts (separated by double EOL)
|
115 |
+
list($headers, $response) = explode("\r\n\r\n", $response, 2);
|
116 |
+
|
117 |
+
// Explode response headers
|
118 |
+
$lines = explode("\r\n", $headers);
|
119 |
+
|
120 |
+
// If the status code is 100, the API server must send a final response
|
121 |
+
// We need to explode the response again to get the actual response
|
122 |
+
if (preg_match('#^HTTP/1.1 100#', $lines[0])) {
|
123 |
+
list($headers, $response) = explode("\r\n\r\n", $response, 2);
|
124 |
+
$lines = explode("\r\n", $headers);
|
125 |
+
}
|
126 |
+
|
127 |
+
// Get the HTTP response code from the first line
|
128 |
+
$first = array_shift($lines);
|
129 |
+
$pattern = '#^HTTP/1.1 ([0-9]{3})#';
|
130 |
+
preg_match($pattern, $first, $matches);
|
131 |
+
$code = $matches[1];
|
132 |
+
|
133 |
+
// Parse the remaining headers into an associative array
|
134 |
+
$headers = array();
|
135 |
+
foreach ($lines as $line) {
|
136 |
+
list($k, $v) = explode(': ', $line, 2);
|
137 |
+
$headers[strtolower($k)] = $v;
|
138 |
+
}
|
139 |
+
|
140 |
+
// If the response body is not a JSON encoded string
|
141 |
+
// we'll return the entire response body
|
142 |
+
if (!$body = json_decode($response)) {
|
143 |
+
$body = $response;
|
144 |
+
}
|
145 |
+
|
146 |
+
return array('code' => $code, 'body' => $body, 'headers' => $headers);
|
147 |
+
}
|
148 |
+
}
|
trunk/includes/Dropbox/OAuth/Consumer/WordPress.php
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* OAuth consumer using the WordPress API
|
5 |
+
* @author David Anderson <david@wordshell.net>
|
6 |
+
* @link https://github.com/DavidAnderson684/Dropbox
|
7 |
+
* @package Dropbox\OAuth
|
8 |
+
* @subpackage Consumer
|
9 |
+
*/
|
10 |
+
|
11 |
+
class Dropbox_ConsumerWordPress extends Dropbox_ConsumerAbstract
|
12 |
+
{
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Set properties and begin authentication
|
16 |
+
* @param string $key
|
17 |
+
* @param string $secret
|
18 |
+
* @param \Dropbox\OAuth\Consumer\StorageInterface $storage
|
19 |
+
* @param string $callback
|
20 |
+
*/
|
21 |
+
public function __construct($key, $secret, Dropbox_StorageInterface $storage, $callback = null)
|
22 |
+
{
|
23 |
+
// Check we are in a WordPress environment
|
24 |
+
if (!defined('ABSPATH')) {
|
25 |
+
throw new Dropbox_Exception('The WordPress OAuth consumer requires a WordPress environment');
|
26 |
+
}
|
27 |
+
|
28 |
+
$this->consumerKey = $key;
|
29 |
+
$this->consumerSecret = $secret;
|
30 |
+
$this->storage = $storage;
|
31 |
+
$this->callback = $callback;
|
32 |
+
$this->authenticate();
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Execute an API call
|
37 |
+
* @param string $method The HTTP method
|
38 |
+
* @param string $url The API endpoint
|
39 |
+
* @param string $call The API method to call
|
40 |
+
* @param array $additional Additional parameters
|
41 |
+
* @return array
|
42 |
+
*/
|
43 |
+
public function fetch($method, $url, $call, array $additional = array())
|
44 |
+
{
|
45 |
+
// Get the signed request URL
|
46 |
+
$request = $this->getSignedRequest($method, $url, $call, $additional);
|
47 |
+
if ($method == 'GET') {
|
48 |
+
$args = array ( );
|
49 |
+
$response = wp_remote_get($request['url'], $args);
|
50 |
+
$this->outFile = null;
|
51 |
+
} elseif ($method == 'POST') {
|
52 |
+
$args = array( 'body' => $request['postfields'] );
|
53 |
+
$response = wp_remote_post($request['url'], $args );
|
54 |
+
} elseif ($method == 'PUT' && $this->inFile) {
|
55 |
+
return new WP_Error('unsupported', __("WordPress does not have a native HTTP PUT function"));
|
56 |
+
}
|
57 |
+
|
58 |
+
// If the response body is not a JSON encoded string
|
59 |
+
// we'll return the entire response body
|
60 |
+
// Important to do this first, as the next section relies on the decoding having taken place
|
61 |
+
if (!$body = json_decode($response['body'])) {
|
62 |
+
$body = $response['body'];
|
63 |
+
}
|
64 |
+
|
65 |
+
// Check if an error occurred and throw an Exception. This is part of the authentication process - don't modify.
|
66 |
+
if (!empty($body->error)) {
|
67 |
+
$message = $body->error . ' (Status Code: ' . $response['code'] . ')';
|
68 |
+
throw new Dropbox_Exception($message);
|
69 |
+
}
|
70 |
+
|
71 |
+
if (is_wp_error($response)) {
|
72 |
+
$message = $response->get_error_message();
|
73 |
+
throw new Dropbox_Exception($message);
|
74 |
+
}
|
75 |
+
|
76 |
+
$results = array ( 'body' => $body, 'code' => $response['response']['code'], 'headers' => $response['headers'] );
|
77 |
+
return $results;
|
78 |
+
}
|
79 |
+
|
80 |
+
}
|
trunk/includes/Dropbox/OAuth/Consumer/ca-bundle.pem
ADDED
@@ -0,0 +1,3920 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
##
|
2 |
+
## ca-bundle.crt -- Bundle of CA Root Certificates
|
3 |
+
##
|
4 |
+
## Certificate data from Mozilla as of: Thu Oct 18 19:05:59 2012
|
5 |
+
##
|
6 |
+
## This is a bundle of X.509 certificates of public Certificate Authorities
|
7 |
+
## (CA). These were automatically extracted from Mozilla's root certificates
|
8 |
+
## file (certdata.txt). This file can be found in the mozilla source tree:
|
9 |
+
## http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1
|
10 |
+
##
|
11 |
+
## It contains the certificates in PEM format and therefore
|
12 |
+
## can be directly used with curl / libcurl / php_curl, or with
|
13 |
+
## an Apache+mod_ssl webserver for SSL client authentication.
|
14 |
+
## Just configure this file as the SSLCACertificateFile.
|
15 |
+
##
|
16 |
+
|
17 |
+
# @(#) $RCSfile: certdata.txt,v $ $Revision: 1.86 $ $Date: 2012/10/18 16:26:52 $
|
18 |
+
|
19 |
+
GTE CyberTrust Global Root
|
20 |
+
==========================
|
21 |
+
-----BEGIN CERTIFICATE-----
|
22 |
+
MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUg
|
23 |
+
Q29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEG
|
24 |
+
A1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJvb3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEz
|
25 |
+
MjM1OTAwWjB1MQswCQYDVQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQL
|
26 |
+
Ex5HVEUgQ3liZXJUcnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0
|
27 |
+
IEdsb2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrHiM3dFw4u
|
28 |
+
sJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTSr41tiGeA5u2ylc9yMcql
|
29 |
+
HHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X404Wqk2kmhXBIgD8SFcd5tB8FLztimQID
|
30 |
+
AQABMA0GCSqGSIb3DQEBBAUAA4GBAG3rGwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMW
|
31 |
+
M4ETCJ57NE7fQMh017l93PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OF
|
32 |
+
NMQkpw0PlZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/
|
33 |
+
-----END CERTIFICATE-----
|
34 |
+
|
35 |
+
Thawte Server CA
|
36 |
+
================
|
37 |
+
-----BEGIN CERTIFICATE-----
|
38 |
+
MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT
|
39 |
+
DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs
|
40 |
+
dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UE
|
41 |
+
AxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5j
|
42 |
+
b20wHhcNOTYwODAxMDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNV
|
43 |
+
BAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29u
|
44 |
+
c3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcG
|
45 |
+
A1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0
|
46 |
+
ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl
|
47 |
+
/Kj0R1HahbUgdJSGHg91yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg7
|
48 |
+
1CcEJRCXL+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGjEzAR
|
49 |
+
MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG7oWDTSEwjsrZqG9J
|
50 |
+
GubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6eQNuozDJ0uW8NxuOzRAvZim+aKZuZ
|
51 |
+
GCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZqdq5snUb9kLy78fyGPmJvKP/iiMucEc=
|
52 |
+
-----END CERTIFICATE-----
|
53 |
+
|
54 |
+
Thawte Premium Server CA
|
55 |
+
========================
|
56 |
+
-----BEGIN CERTIFICATE-----
|
57 |
+
MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkExFTATBgNVBAgT
|
58 |
+
DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs
|
59 |
+
dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UE
|
60 |
+
AxMYVGhhd3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZl
|
61 |
+
ckB0aGF3dGUuY29tMB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYT
|
62 |
+
AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU
|
63 |
+
VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2
|
64 |
+
aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNlcnZlciBDQTEoMCYGCSqGSIb3DQEJARYZ
|
65 |
+
cHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2
|
66 |
+
aovXwlue2oFBYo847kkEVdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIh
|
67 |
+
Udib0GfQug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMRuHM/
|
68 |
+
qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQAm
|
69 |
+
SCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUIhfzJATj/Tb7yFkJD57taRvvBxhEf
|
70 |
+
8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JMpAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7t
|
71 |
+
UCemDaYj+bvLpgcUQg==
|
72 |
+
-----END CERTIFICATE-----
|
73 |
+
|
74 |
+
Equifax Secure CA
|
75 |
+
=================
|
76 |
+
-----BEGIN CERTIFICATE-----
|
77 |
+
MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEQMA4GA1UE
|
78 |
+
ChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
|
79 |
+
MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoT
|
80 |
+
B0VxdWlmYXgxLTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCB
|
81 |
+
nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPR
|
82 |
+
fM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW
|
83 |
+
8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAG
|
84 |
+
A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UE
|
85 |
+
CxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoG
|
86 |
+
A1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvS
|
87 |
+
spXXR9gjIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMB
|
88 |
+
Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAFjOKer89961
|
89 |
+
zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y7qj/WsjTVbJmcVfewCHrPSqnI0kB
|
90 |
+
BIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95
|
91 |
+
70+sB3c4
|
92 |
+
-----END CERTIFICATE-----
|
93 |
+
|
94 |
+
Digital Signature Trust Co. Global CA 1
|
95 |
+
=======================================
|
96 |
+
-----BEGIN CERTIFICATE-----
|
97 |
+
MIIDKTCCApKgAwIBAgIENnAVljANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJVUzEkMCIGA1UE
|
98 |
+
ChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQLEwhEU1RDQSBFMTAeFw05ODEy
|
99 |
+
MTAxODEwMjNaFw0xODEyMTAxODQwMjNaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFs
|
100 |
+
IFNpZ25hdHVyZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUxMIGdMA0GCSqGSIb3DQEBAQUA
|
101 |
+
A4GLADCBhwKBgQCgbIGpzzQeJN3+hijM3oMv+V7UQtLodGBmE5gGHKlREmlvMVW5SXIACH7TpWJE
|
102 |
+
NySZj9mDSI+ZbZUTu0M7LklOiDfBu1h//uG9+LthzfNHwJmm8fOR6Hh8AMthyUQncWlVSn5JTe2i
|
103 |
+
o74CTADKAqjuAQIxZA9SLRN0dja1erQtcQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBo
|
104 |
+
BgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0
|
105 |
+
dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTExDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw
|
106 |
+
IoAPMTk5ODEyMTAxODEwMjNagQ8yMDE4MTIxMDE4MTAyM1owCwYDVR0PBAQDAgEGMB8GA1UdIwQY
|
107 |
+
MBaAFGp5fpFpRhgTCgJ3pVlbYJglDqL4MB0GA1UdDgQWBBRqeX6RaUYYEwoCd6VZW2CYJQ6i+DAM
|
108 |
+
BgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4GB
|
109 |
+
ACIS2Hod3IEGtgllsofIH160L+nEHvI8wbsEkBFKg05+k7lNQseSJqBcNJo4cvj9axY+IO6CizEq
|
110 |
+
kzaFI4iKPANo08kJD038bKTaKHKTDomAsH3+gG9lbRgzl4vCa4nuYD3Im+9/KzJic5PLPON74nZ4
|
111 |
+
RbyhkwS7hp86W0N6w4pl
|
112 |
+
-----END CERTIFICATE-----
|
113 |
+
|
114 |
+
Digital Signature Trust Co. Global CA 3
|
115 |
+
=======================================
|
116 |
+
-----BEGIN CERTIFICATE-----
|
117 |
+
MIIDKTCCApKgAwIBAgIENm7TzjANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJVUzEkMCIGA1UE
|
118 |
+
ChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQLEwhEU1RDQSBFMjAeFw05ODEy
|
119 |
+
MDkxOTE3MjZaFw0xODEyMDkxOTQ3MjZaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFs
|
120 |
+
IFNpZ25hdHVyZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUyMIGdMA0GCSqGSIb3DQEBAQUA
|
121 |
+
A4GLADCBhwKBgQC/k48Xku8zExjrEH9OFr//Bo8qhbxe+SSmJIi2A7fBw18DW9Fvrn5C6mYjuGOD
|
122 |
+
VvsoLeE4i7TuqAHhzhy2iCoiRoX7n6dwqUcUP87eZfCocfdPJmyMvMa1795JJ/9IKn3oTQPMx7JS
|
123 |
+
xhcxEzu1TdvIxPbDDyQq2gyd55FbgM2UnQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBo
|
124 |
+
BgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0
|
125 |
+
dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTIxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw
|
126 |
+
IoAPMTk5ODEyMDkxOTE3MjZagQ8yMDE4MTIwOTE5MTcyNlowCwYDVR0PBAQDAgEGMB8GA1UdIwQY
|
127 |
+
MBaAFB6CTShlgDzJQW6sNS5ay97u+DlbMB0GA1UdDgQWBBQegk0oZYA8yUFurDUuWsve7vg5WzAM
|
128 |
+
BgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4GB
|
129 |
+
AEeNg61i8tuwnkUiBbmi1gMOOHLnnvx75pO2mqWilMg0HZHRxdf0CiUPPXiBng+xZ8SQTGPdXqfi
|
130 |
+
up/1902lMXucKS1M/mQ+7LZT/uqb7YLbdHVLB3luHtgZg3Pe9T7Qtd7nS2h9Qy4qIOF+oHhEngj1
|
131 |
+
mPnHfxsb1gYgAlihw6ID
|
132 |
+
-----END CERTIFICATE-----
|
133 |
+
|
134 |
+
Verisign Class 3 Public Primary Certification Authority
|
135 |
+
=======================================================
|
136 |
+
-----BEGIN CERTIFICATE-----
|
137 |
+
MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMx
|
138 |
+
FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5
|
139 |
+
IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVow
|
140 |
+
XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz
|
141 |
+
IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
|
142 |
+
A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94
|
143 |
+
f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol
|
144 |
+
hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBAgUAA4GBALtMEivPLCYA
|
145 |
+
TxQT3ab7/AoRhIzzKBxnki98tsX63/Dolbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59Ah
|
146 |
+
WM1pF+NEHJwZRDmJXNycAA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2Omuf
|
147 |
+
Tqj/ZA1k
|
148 |
+
-----END CERTIFICATE-----
|
149 |
+
|
150 |
+
Verisign Class 1 Public Primary Certification Authority - G2
|
151 |
+
============================================================
|
152 |
+
-----BEGIN CERTIFICATE-----
|
153 |
+
MIIDAjCCAmsCEEzH6qqYPnHTkxD4PTqJkZIwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT
|
154 |
+
MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMgUHJpbWFy
|
155 |
+
eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
|
156 |
+
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
|
157 |
+
dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT
|
158 |
+
MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMgUHJpbWFy
|
159 |
+
eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
|
160 |
+
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
|
161 |
+
dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCq0Lq+Fi24g9TK0g+8djHKlNgd
|
162 |
+
k4xWArzZbxpvUjZudVYKVdPfQ4chEWWKfo+9Id5rMj8bhDSVBZ1BNeuS65bdqlk/AVNtmU/t5eIq
|
163 |
+
WpDBucSmFc/IReumXY6cPvBkJHalzasab7bYe1FhbqZ/h8jit+U03EGI6glAvnOSPWvndQIDAQAB
|
164 |
+
MA0GCSqGSIb3DQEBBQUAA4GBAKlPww3HZ74sy9mozS11534Vnjty637rXC0Jh9ZrbWB85a7FkCMM
|
165 |
+
XErQr7Fd88e2CtvgFZMN3QO8x3aKtd1Pw5sTdbgBwObJW2uluIncrKTdcu1OofdPvAbT6shkdHvC
|
166 |
+
lUGcZXNY8ZCaPGqxmMnEh7zPRW1F4m4iP/68DzFc6PLZ
|
167 |
+
-----END CERTIFICATE-----
|
168 |
+
|
169 |
+
Verisign Class 2 Public Primary Certification Authority - G2
|
170 |
+
============================================================
|
171 |
+
-----BEGIN CERTIFICATE-----
|
172 |
+
MIIDAzCCAmwCEQC5L2DMiJ+hekYJuFtwbIqvMA0GCSqGSIb3DQEBBQUAMIHBMQswCQYDVQQGEwJV
|
173 |
+
UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGljIFByaW1h
|
174 |
+
cnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNp
|
175 |
+
Z24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1
|
176 |
+
c3QgTmV0d29yazAeFw05ODA1MTgwMDAwMDBaFw0yODA4MDEyMzU5NTlaMIHBMQswCQYDVQQGEwJV
|
177 |
+
UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGljIFByaW1h
|
178 |
+
cnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNp
|
179 |
+
Z24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1
|
180 |
+
c3QgTmV0d29yazCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAp4gBIXQs5xoD8JjhlzwPIQjx
|
181 |
+
nNuX6Zr8wgQGE75fUsjMHiwSViy4AWkszJkfrbCWrnkE8hM5wXuYuggs6MKEEyyqaekJ9MepAqRC
|
182 |
+
wiNPStjwDqL7MWzJ5m+ZJwf15vRMeJ5t60aG+rmGyVTyssSv1EYcWskVMP8NbPUtDm3Of3cCAwEA
|
183 |
+
ATANBgkqhkiG9w0BAQUFAAOBgQByLvl/0fFx+8Se9sVeUYpAmLho+Jscg9jinb3/7aHmZuovCfTK
|
184 |
+
1+qlK5X2JGCGTUQug6XELaDTrnhpb3LabK4I8GOSN+a7xDAXrXfMSTWqz9iP0b63GJZHc2pUIjRk
|
185 |
+
LbYWm1lbtFFZOrMLFPQS32eg9K0yZF6xRnInjBJ7xUS0rg==
|
186 |
+
-----END CERTIFICATE-----
|
187 |
+
|
188 |
+
Verisign Class 3 Public Primary Certification Authority - G2
|
189 |
+
============================================================
|
190 |
+
-----BEGIN CERTIFICATE-----
|
191 |
+
MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT
|
192 |
+
MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy
|
193 |
+
eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
|
194 |
+
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
|
195 |
+
dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT
|
196 |
+
MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy
|
197 |
+
eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
|
198 |
+
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
|
199 |
+
dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCO
|
200 |
+
FoUgRm1HP9SFIIThbbP4pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71
|
201 |
+
lSk8UOg013gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwIDAQAB
|
202 |
+
MA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSkU01UbSuvDV1Ai2TT
|
203 |
+
1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7iF6YM40AIOw7n60RzKprxaZLvcRTD
|
204 |
+
Oaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpYoJ2daZH9
|
205 |
+
-----END CERTIFICATE-----
|
206 |
+
|
207 |
+
GlobalSign Root CA
|
208 |
+
==================
|
209 |
+
-----BEGIN CERTIFICATE-----
|
210 |
+
MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx
|
211 |
+
GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds
|
212 |
+
b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV
|
213 |
+
BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD
|
214 |
+
VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa
|
215 |
+
DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc
|
216 |
+
THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb
|
217 |
+
Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP
|
218 |
+
c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX
|
219 |
+
gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
|
220 |
+
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF
|
221 |
+
AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj
|
222 |
+
Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG
|
223 |
+
j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH
|
224 |
+
hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC
|
225 |
+
X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
|
226 |
+
-----END CERTIFICATE-----
|
227 |
+
|
228 |
+
GlobalSign Root CA - R2
|
229 |
+
=======================
|
230 |
+
-----BEGIN CERTIFICATE-----
|
231 |
+
MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv
|
232 |
+
YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh
|
233 |
+
bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT
|
234 |
+
aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln
|
235 |
+
bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6
|
236 |
+
ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp
|
237 |
+
s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN
|
238 |
+
S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL
|
239 |
+
TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C
|
240 |
+
ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
|
241 |
+
FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i
|
242 |
+
YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN
|
243 |
+
BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp
|
244 |
+
9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu
|
245 |
+
01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7
|
246 |
+
9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
|
247 |
+
TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
|
248 |
+
-----END CERTIFICATE-----
|
249 |
+
|
250 |
+
ValiCert Class 1 VA
|
251 |
+
===================
|
252 |
+
-----BEGIN CERTIFICATE-----
|
253 |
+
MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp
|
254 |
+
b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
|
255 |
+
YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh
|
256 |
+
bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIy
|
257 |
+
MjM0OFoXDTE5MDYyNTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0
|
258 |
+
d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEg
|
259 |
+
UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0
|
260 |
+
LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA
|
261 |
+
A4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9YLqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIi
|
262 |
+
GQj4/xEjm84H9b9pGib+TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCm
|
263 |
+
DuJWBQ8YTfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0LBwG
|
264 |
+
lN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLWI8sogTLDAHkY7FkX
|
265 |
+
icnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPwnXS3qT6gpf+2SQMT2iLM7XGCK5nP
|
266 |
+
Orf1LXLI
|
267 |
+
-----END CERTIFICATE-----
|
268 |
+
|
269 |
+
ValiCert Class 2 VA
|
270 |
+
===================
|
271 |
+
-----BEGIN CERTIFICATE-----
|
272 |
+
MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp
|
273 |
+
b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
|
274 |
+
YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh
|
275 |
+
bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw
|
276 |
+
MTk1NFoXDTE5MDYyNjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0
|
277 |
+
d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIg
|
278 |
+
UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0
|
279 |
+
LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA
|
280 |
+
A4GNADCBiQKBgQDOOnHK5avIWZJV16vYdA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVC
|
281 |
+
CSRrCl6zfN1SLUzm1NZ9WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7Rf
|
282 |
+
ZHM047QSv4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9vUJSZ
|
283 |
+
SWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTuIYEZoDJJKPTEjlbV
|
284 |
+
UjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwCW/POuZ6lcg5Ktz885hZo+L7tdEy8
|
285 |
+
W9ViH0Pd
|
286 |
+
-----END CERTIFICATE-----
|
287 |
+
|
288 |
+
RSA Root Certificate 1
|
289 |
+
======================
|
290 |
+
-----BEGIN CERTIFICATE-----
|
291 |
+
MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp
|
292 |
+
b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
|
293 |
+
YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh
|
294 |
+
bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw
|
295 |
+
MjIzM1oXDTE5MDYyNjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0
|
296 |
+
d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMg
|
297 |
+
UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0
|
298 |
+
LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA
|
299 |
+
A4GNADCBiQKBgQDjmFGWHOjVsQaBalfDcnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td
|
300 |
+
3zZxFJmP3MKS8edgkpfs2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89H
|
301 |
+
BFx1cQqYJJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliEZwgs
|
302 |
+
3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJn0WuPIqpsHEzXcjF
|
303 |
+
V9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/APhmcGcwTTYJBtYze4D1gCCAPRX5r
|
304 |
+
on+jjBXu
|
305 |
+
-----END CERTIFICATE-----
|
306 |
+
|
307 |
+
Verisign Class 1 Public Primary Certification Authority - G3
|
308 |
+
============================================================
|
309 |
+
-----BEGIN CERTIFICATE-----
|
310 |
+
MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
|
311 |
+
UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
|
312 |
+
cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
|
313 |
+
IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
|
314 |
+
dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
|
315 |
+
CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
|
316 |
+
dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
|
317 |
+
cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDEgUHVibGljIFByaW1hcnkg
|
318 |
+
Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
|
319 |
+
ggEBAN2E1Lm0+afY8wR4nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/E
|
320 |
+
bRrsC+MO8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjVojYJ
|
321 |
+
rKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjbPG7PoBMAGrgnoeS+
|
322 |
+
Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP26KbqxzcSXKMpHgLZ2x87tNcPVkeB
|
323 |
+
FQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vrn5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
|
324 |
+
q2aN17O6x5q25lXQBfGfMY1aqtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/N
|
325 |
+
y9Sn2WCVhDr4wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3
|
326 |
+
ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrspSCAaWihT37h
|
327 |
+
a88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4E1Z5T21Q6huwtVexN2ZYI/Pc
|
328 |
+
D98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g==
|
329 |
+
-----END CERTIFICATE-----
|
330 |
+
|
331 |
+
Verisign Class 2 Public Primary Certification Authority - G3
|
332 |
+
============================================================
|
333 |
+
-----BEGIN CERTIFICATE-----
|
334 |
+
MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJBgNVBAYTAlVT
|
335 |
+
MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29y
|
336 |
+
azE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ug
|
337 |
+
b25seTFFMEMGA1UEAxM8VmVyaVNpZ24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0
|
338 |
+
aW9uIEF1dGhvcml0eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJ
|
339 |
+
BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1
|
340 |
+
c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9y
|
341 |
+
aXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBD
|
342 |
+
ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
|
343 |
+
AQEArwoNwtUs22e5LeWUJ92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6
|
344 |
+
tW8UvxDOJxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUYwZF7
|
345 |
+
C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9okoqQHgiBVrKtaaNS
|
346 |
+
0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjNqWm6o+sdDZykIKbBoMXRRkwXbdKs
|
347 |
+
Zj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/ESrg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0
|
348 |
+
JhU8wI1NQ0kdvekhktdmnLfexbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf
|
349 |
+
0xwLRtxyID+u7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU
|
350 |
+
sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RIsH/7NiXaldDx
|
351 |
+
JBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTPcjnhsUPgKM+351psE2tJs//j
|
352 |
+
GHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q
|
353 |
+
-----END CERTIFICATE-----
|
354 |
+
|
355 |
+
Verisign Class 3 Public Primary Certification Authority - G3
|
356 |
+
============================================================
|
357 |
+
-----BEGIN CERTIFICATE-----
|
358 |
+
MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
|
359 |
+
UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
|
360 |
+
cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
|
361 |
+
IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
|
362 |
+
dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
|
363 |
+
CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
|
364 |
+
dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
|
365 |
+
cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg
|
366 |
+
Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
|
367 |
+
ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1
|
368 |
+
EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc
|
369 |
+
cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw
|
370 |
+
EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj
|
371 |
+
055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
|
372 |
+
ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f
|
373 |
+
j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
|
374 |
+
/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0
|
375 |
+
xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa
|
376 |
+
t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
|
377 |
+
-----END CERTIFICATE-----
|
378 |
+
|
379 |
+
Verisign Class 4 Public Primary Certification Authority - G3
|
380 |
+
============================================================
|
381 |
+
-----BEGIN CERTIFICATE-----
|
382 |
+
MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
|
383 |
+
UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
|
384 |
+
cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
|
385 |
+
IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
|
386 |
+
dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
|
387 |
+
CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
|
388 |
+
dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
|
389 |
+
cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkg
|
390 |
+
Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
|
391 |
+
ggEBAK3LpRFpxlmr8Y+1GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaS
|
392 |
+
tBO3IFsJ+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0GbdU6LM
|
393 |
+
8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLmNxdLMEYH5IBtptiW
|
394 |
+
Lugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XYufTsgsbSPZUd5cBPhMnZo0QoBmrX
|
395 |
+
Razwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
|
396 |
+
j/ola09b5KROJ1WrIhVZPMq1CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXtt
|
397 |
+
mhwwjIDLk5Mqg6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm
|
398 |
+
fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c2NU8Qh0XwRJd
|
399 |
+
RTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/bLvSHgCwIe34QWKCudiyxLtG
|
400 |
+
UPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg==
|
401 |
+
-----END CERTIFICATE-----
|
402 |
+
|
403 |
+
Entrust.net Secure Server CA
|
404 |
+
============================
|
405 |
+
-----BEGIN CERTIFICATE-----
|
406 |
+
MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMCVVMxFDASBgNV
|
407 |
+
BAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5uZXQvQ1BTIGluY29ycC4gYnkg
|
408 |
+
cmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRl
|
409 |
+
ZDE6MDgGA1UEAxMxRW50cnVzdC5uZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhv
|
410 |
+
cml0eTAeFw05OTA1MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIG
|
411 |
+
A1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBi
|
412 |
+
eSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1p
|
413 |
+
dGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0
|
414 |
+
aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQ
|
415 |
+
aO2f55M28Qpku0f1BBc/I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5
|
416 |
+
gXpa0zf3wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OCAdcw
|
417 |
+
ggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHboIHYpIHVMIHSMQsw
|
418 |
+
CQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5l
|
419 |
+
dC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF
|
420 |
+
bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENl
|
421 |
+
cnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu
|
422 |
+
dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0MFqBDzIwMTkw
|
423 |
+
NTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7UISX8+1i0Bow
|
424 |
+
HQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAaMAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EA
|
425 |
+
BAwwChsEVjQuMAMCBJAwDQYJKoZIhvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyN
|
426 |
+
Ewr75Ji174z4xRAN95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9
|
427 |
+
n9cd2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI=
|
428 |
+
-----END CERTIFICATE-----
|
429 |
+
|
430 |
+
Entrust.net Premium 2048 Secure Server CA
|
431 |
+
=========================================
|
432 |
+
-----BEGIN CERTIFICATE-----
|
433 |
+
MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u
|
434 |
+
ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp
|
435 |
+
bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV
|
436 |
+
BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx
|
437 |
+
NzUwNTFaFw0xOTEyMjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3
|
438 |
+
d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl
|
439 |
+
MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u
|
440 |
+
ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
|
441 |
+
MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL
|
442 |
+
Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr
|
443 |
+
hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW
|
444 |
+
nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi
|
445 |
+
VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo3QwcjARBglghkgBhvhC
|
446 |
+
AQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGAvtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdER
|
447 |
+
gL7YibkIozH5oSQJFrlwMB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0B
|
448 |
+
AQUFAAOCAQEAWUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo
|
449 |
+
oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQh7A6tcOdBTcS
|
450 |
+
o8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18f3v/rxzP5tsHrV7bhZ3QKw0z
|
451 |
+
2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfNB/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjX
|
452 |
+
OP/swNlQ8C5LWK5Gb9Auw2DaclVyvUxFnmG6v4SBkgPR0ml8xQ==
|
453 |
+
-----END CERTIFICATE-----
|
454 |
+
|
455 |
+
Baltimore CyberTrust Root
|
456 |
+
=========================
|
457 |
+
-----BEGIN CERTIFICATE-----
|
458 |
+
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE
|
459 |
+
ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li
|
460 |
+
ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC
|
461 |
+
SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs
|
462 |
+
dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME
|
463 |
+
uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB
|
464 |
+
UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C
|
465 |
+
G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9
|
466 |
+
XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr
|
467 |
+
l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI
|
468 |
+
VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB
|
469 |
+
BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh
|
470 |
+
cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5
|
471 |
+
hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa
|
472 |
+
Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H
|
473 |
+
RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
|
474 |
+
-----END CERTIFICATE-----
|
475 |
+
|
476 |
+
Equifax Secure Global eBusiness CA
|
477 |
+
==================================
|
478 |
+
-----BEGIN CERTIFICATE-----
|
479 |
+
MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT
|
480 |
+
RXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBTZWN1cmUgR2xvYmFsIGVCdXNp
|
481 |
+
bmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIwMDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMx
|
482 |
+
HDAaBgNVBAoTE0VxdWlmYXggU2VjdXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEds
|
483 |
+
b2JhbCBlQnVzaW5lc3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRV
|
484 |
+
PEnCUdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc58O/gGzN
|
485 |
+
qfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/o5brhTMhHD4ePmBudpxn
|
486 |
+
hcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAHMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j
|
487 |
+
BBgwFoAUvqigdHJQa0S3ySPY+6j/s1draGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hs
|
488 |
+
MA0GCSqGSIb3DQEBBAUAA4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okEN
|
489 |
+
I7SS+RkAZ70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv8qIY
|
490 |
+
NMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV
|
491 |
+
-----END CERTIFICATE-----
|
492 |
+
|
493 |
+
Equifax Secure eBusiness CA 1
|
494 |
+
=============================
|
495 |
+
-----BEGIN CERTIFICATE-----
|
496 |
+
MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT
|
497 |
+
RXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENB
|
498 |
+
LTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQwMDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UE
|
499 |
+
ChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNz
|
500 |
+
IENBLTEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ
|
501 |
+
1MRoRvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBuWqDZQu4a
|
502 |
+
IZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKwEnv+j6YDAgMBAAGjZjBk
|
503 |
+
MBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEp4MlIR21kW
|
504 |
+
Nl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRKeDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQF
|
505 |
+
AAOBgQB1W6ibAxHm6VZMzfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5
|
506 |
+
lSE/9dR+WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN/Bf+
|
507 |
+
KpYrtWKmpj29f5JZzVoqgrI3eQ==
|
508 |
+
-----END CERTIFICATE-----
|
509 |
+
|
510 |
+
Equifax Secure eBusiness CA 2
|
511 |
+
=============================
|
512 |
+
-----BEGIN CERTIFICATE-----
|
513 |
+
MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEXMBUGA1UE
|
514 |
+
ChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0y
|
515 |
+
MB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoT
|
516 |
+
DkVxdWlmYXggU2VjdXJlMSYwJAYDVQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCB
|
517 |
+
nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn
|
518 |
+
2Z0GvxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/BPO3QSQ5
|
519 |
+
BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0CAwEAAaOCAQkwggEFMHAG
|
520 |
+
A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUx
|
521 |
+
JjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoG
|
522 |
+
A1UdEAQTMBGBDzIwMTkwNjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9e
|
523 |
+
uSBIplBqy/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQFMAMB
|
524 |
+
Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAAyGgq3oThr1
|
525 |
+
jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia
|
526 |
+
78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUm
|
527 |
+
V+GRMOrN
|
528 |
+
-----END CERTIFICATE-----
|
529 |
+
|
530 |
+
AddTrust Low-Value Services Root
|
531 |
+
================================
|
532 |
+
-----BEGIN CERTIFICATE-----
|
533 |
+
MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
|
534 |
+
QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRU
|
535 |
+
cnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMwMTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQsw
|
536 |
+
CQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBO
|
537 |
+
ZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEB
|
538 |
+
AQUAA4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ulCDtbKRY6
|
539 |
+
54eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6ntGO0/7Gcrjyvd7ZWxbWr
|
540 |
+
oulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyldI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1
|
541 |
+
Zmne3yzxbrww2ywkEtvrNTVokMsAsJchPXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJui
|
542 |
+
GMx1I4S+6+JNM3GOGvDC+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8w
|
543 |
+
HQYDVR0OBBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8EBTAD
|
544 |
+
AQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBlMQswCQYDVQQGEwJT
|
545 |
+
RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEw
|
546 |
+
HwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxt
|
547 |
+
ZBsfzQ3duQH6lmM0MkhHma6X7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0Ph
|
548 |
+
iVYrqW9yTkkz43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY
|
549 |
+
eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJlpz/+0WatC7xr
|
550 |
+
mYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOAWiFeIc9TVPC6b4nbqKqVz4vj
|
551 |
+
ccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk=
|
552 |
+
-----END CERTIFICATE-----
|
553 |
+
|
554 |
+
AddTrust External Root
|
555 |
+
======================
|
556 |
+
-----BEGIN CERTIFICATE-----
|
557 |
+
MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
|
558 |
+
QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD
|
559 |
+
VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw
|
560 |
+
NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU
|
561 |
+
cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg
|
562 |
+
Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821
|
563 |
+
+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw
|
564 |
+
Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo
|
565 |
+
aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy
|
566 |
+
2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7
|
567 |
+
7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P
|
568 |
+
BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL
|
569 |
+
VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk
|
570 |
+
VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB
|
571 |
+
IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl
|
572 |
+
j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
|
573 |
+
6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355
|
574 |
+
e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u
|
575 |
+
G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
|
576 |
+
-----END CERTIFICATE-----
|
577 |
+
|
578 |
+
AddTrust Public Services Root
|
579 |
+
=============================
|
580 |
+
-----BEGIN CERTIFICATE-----
|
581 |
+
MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
|
582 |
+
QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSAwHgYDVQQDExdBZGRU
|
583 |
+
cnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAxMDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJ
|
584 |
+
BgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5l
|
585 |
+
dHdvcmsxIDAeBgNVBAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEF
|
586 |
+
AAOCAQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV6tsfSlbu
|
587 |
+
nyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nXGCwwfQ56HmIexkvA/X1i
|
588 |
+
d9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnPdzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSG
|
589 |
+
Aa2Il+tmzV7R/9x98oTaunet3IAIx6eH1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAw
|
590 |
+
HM+A+WD+eeSI8t0A65RF62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0G
|
591 |
+
A1UdDgQWBBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
|
592 |
+
/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDELMAkGA1UEBhMCU0Ux
|
593 |
+
FDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29yazEgMB4G
|
594 |
+
A1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4
|
595 |
+
JNojVhaTdt02KLmuG7jD8WS6IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL
|
596 |
+
+YPoRNWyQSW/iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao
|
597 |
+
GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh4SINhwBk/ox9
|
598 |
+
Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQmXiLsks3/QppEIW1cxeMiHV9H
|
599 |
+
EufOX1362KqxMy3ZdvJOOjMMK7MtkAY=
|
600 |
+
-----END CERTIFICATE-----
|
601 |
+
|
602 |
+
AddTrust Qualified Certificates Root
|
603 |
+
====================================
|
604 |
+
-----BEGIN CERTIFICATE-----
|
605 |
+
MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
|
606 |
+
QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSMwIQYDVQQDExpBZGRU
|
607 |
+
cnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcx
|
608 |
+
CzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQ
|
609 |
+
IE5ldHdvcmsxIzAhBgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG
|
610 |
+
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwqxBb/4Oxx
|
611 |
+
64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G87B4pfYOQnrjfxvM0PC3
|
612 |
+
KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i2O+tCBGaKZnhqkRFmhJePp1tUvznoD1o
|
613 |
+
L/BLcHwTOK28FSXx1s6rosAx1i+f4P8UWfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GR
|
614 |
+
wVY18BTcZTYJbqukB8c10cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HU
|
615 |
+
MIHRMB0GA1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/
|
616 |
+
BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6FrpGkwZzELMAkGA1UE
|
617 |
+
BhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29y
|
618 |
+
azEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlmaWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQAD
|
619 |
+
ggEBABmrder4i2VhlRO6aQTvhsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxG
|
620 |
+
GuoYQ992zPlmhpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X
|
621 |
+
dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3P6CxB9bpT9ze
|
622 |
+
RXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9YiQBCYz95OdBEsIJuQRno3eDB
|
623 |
+
iFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5noxqE=
|
624 |
+
-----END CERTIFICATE-----
|
625 |
+
|
626 |
+
Entrust Root Certification Authority
|
627 |
+
====================================
|
628 |
+
-----BEGIN CERTIFICATE-----
|
629 |
+
MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV
|
630 |
+
BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw
|
631 |
+
b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG
|
632 |
+
A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0
|
633 |
+
MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu
|
634 |
+
MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu
|
635 |
+
Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v
|
636 |
+
dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
637 |
+
ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz
|
638 |
+
A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww
|
639 |
+
Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68
|
640 |
+
j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN
|
641 |
+
rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw
|
642 |
+
DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1
|
643 |
+
MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH
|
644 |
+
hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
|
645 |
+
A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM
|
646 |
+
Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa
|
647 |
+
v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS
|
648 |
+
W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0
|
649 |
+
tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8
|
650 |
+
-----END CERTIFICATE-----
|
651 |
+
|
652 |
+
RSA Security 2048 v3
|
653 |
+
====================
|
654 |
+
-----BEGIN CERTIFICATE-----
|
655 |
+
MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6MRkwFwYDVQQK
|
656 |
+
ExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJpdHkgMjA0OCBWMzAeFw0wMTAy
|
657 |
+
MjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAXBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAb
|
658 |
+
BgNVBAsTFFJTQSBTZWN1cml0eSAyMDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
|
659 |
+
AQEAt49VcdKA3XtpeafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7
|
660 |
+
Jylg/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGlwSMiuLgb
|
661 |
+
WhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnhAMFRD0xS+ARaqn1y07iH
|
662 |
+
KrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP
|
663 |
+
+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpuAWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/
|
664 |
+
MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4E
|
665 |
+
FgQUB8NRMKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYcHnmY
|
666 |
+
v/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/Zb5gEydxiKRz44Rj
|
667 |
+
0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+f00/FGj1EVDVwfSQpQgdMWD/YIwj
|
668 |
+
VAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVOrSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395
|
669 |
+
nzIlQnQFgCi/vcEkllgVsRch6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kA
|
670 |
+
pKnXwiJPZ9d37CAFYd4=
|
671 |
+
-----END CERTIFICATE-----
|
672 |
+
|
673 |
+
GeoTrust Global CA
|
674 |
+
==================
|
675 |
+
-----BEGIN CERTIFICATE-----
|
676 |
+
MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
|
677 |
+
Ew1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw
|
678 |
+
MDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j
|
679 |
+
LjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
680 |
+
CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo
|
681 |
+
BbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet
|
682 |
+
8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc
|
683 |
+
T4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU
|
684 |
+
vTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD
|
685 |
+
AQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk
|
686 |
+
DBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q
|
687 |
+
zxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4
|
688 |
+
d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2
|
689 |
+
mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p
|
690 |
+
XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm
|
691 |
+
Mw==
|
692 |
+
-----END CERTIFICATE-----
|
693 |
+
|
694 |
+
GeoTrust Global CA 2
|
695 |
+
====================
|
696 |
+
-----BEGIN CERTIFICATE-----
|
697 |
+
MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN
|
698 |
+
R2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwHhcNMDQwMzA0MDUw
|
699 |
+
MDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j
|
700 |
+
LjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
|
701 |
+
ggEKAoIBAQDvPE1APRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/
|
702 |
+
NTL8Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hLTytCOb1k
|
703 |
+
LUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL5mkWRxHCJ1kDs6ZgwiFA
|
704 |
+
Vvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7S4wMcoKK+xfNAGw6EzywhIdLFnopsk/b
|
705 |
+
HdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQF
|
706 |
+
MAMBAf8wHQYDVR0OBBYEFHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNH
|
707 |
+
K266ZUapEBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6tdEPx7
|
708 |
+
srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv/NgdRN3ggX+d6Yvh
|
709 |
+
ZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywNA0ZF66D0f0hExghAzN4bcLUprbqL
|
710 |
+
OzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkC
|
711 |
+
x1YAzUm5s2x7UwQa4qjJqhIFI8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqF
|
712 |
+
H4z1Ir+rzoPz4iIprn2DQKi6bA==
|
713 |
+
-----END CERTIFICATE-----
|
714 |
+
|
715 |
+
GeoTrust Universal CA
|
716 |
+
=====================
|
717 |
+
-----BEGIN CERTIFICATE-----
|
718 |
+
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
|
742 |
+
P/rmMuGNG2+k5o7Y+SlIis5z/iw=
|
743 |
+
-----END CERTIFICATE-----
|
744 |
+
|
745 |
+
GeoTrust Universal CA 2
|
746 |
+
=======================
|
747 |
+
-----BEGIN CERTIFICATE-----
|
748 |
+
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
|
772 |
+
X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
|
773 |
+
-----END CERTIFICATE-----
|
774 |
+
|
775 |
+
UTN-USER First-Network Applications
|
776 |
+
===================================
|
777 |
+
-----BEGIN CERTIFICATE-----
|
778 |
+
MIIEZDCCA0ygAwIBAgIQRL4Mi1AAJLQR0zYwS8AzdzANBgkqhkiG9w0BAQUFADCBozELMAkGA1UE
|
779 |
+
BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
|
780 |
+
IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzAp
|
781 |
+
BgNVBAMTIlVUTi1VU0VSRmlyc3QtTmV0d29yayBBcHBsaWNhdGlvbnMwHhcNOTkwNzA5MTg0ODM5
|
782 |
+
WhcNMTkwNzA5MTg1NzQ5WjCBozELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5T
|
783 |
+
YWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
|
784 |
+
dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzApBgNVBAMTIlVUTi1VU0VSRmlyc3QtTmV0d29yayBB
|
785 |
+
cHBsaWNhdGlvbnMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCz+5Gh5DZVhawGNFug
|
786 |
+
mliy+LUPBXeDrjKxdpJo7CNKyXY/45y2N3kDuatpjQclthln5LAbGHNhSuh+zdMvZOOmfAz6F4Cj
|
787 |
+
DUeJT1FxL+78P/m4FoCHiZMlIJpDgmkkdihZNaEdwH+DBmQWICzTSaSFtMBhf1EI+GgVkYDLpdXu
|
788 |
+
Ozr0hAReYFmnjDRy7rh4xdE7EkpvfmUnuaRVxblvQ6TFHSyZwFKkeEwVs0CYCGtDxgGwenv1axwi
|
789 |
+
P8vv/6jQOkt2FZ7S0cYu49tXGzKiuG/ohqY/cKvlcJKrRB5AUPuco2LkbG6gyN7igEL66S/ozjIE
|
790 |
+
j3yNtxyjNTwV3Z7DrpelAgMBAAGjgZEwgY4wCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8w
|
791 |
+
HQYDVR0OBBYEFPqGydvguul49Uuo1hXf8NPhahQ8ME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly9j
|
792 |
+
cmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LU5ldHdvcmtBcHBsaWNhdGlvbnMuY3JsMA0G
|
793 |
+
CSqGSIb3DQEBBQUAA4IBAQCk8yXM0dSRgyLQzDKrm5ZONJFUICU0YV8qAhXhi6r/fWRRzwr/vH3Y
|
794 |
+
IWp4yy9Rb/hCHTO967V7lMPDqaAt39EpHx3+jz+7qEUqf9FuVSTiuwL7MT++6LzsQCv4AdRWOOTK
|
795 |
+
RIK1YSAhZ2X28AvnNPilwpyjXEAfhZOVBt5P1CeptqX8Fs1zMT+4ZSfP1FMa8Kxun08FDAOBp4Qp
|
796 |
+
xFq9ZFdyrTvPNximmMatBrTcCKME1SmklpoSZ0qMYEWd8SOasACcaLWYUNPvji6SZbFIPiG+FTAq
|
797 |
+
DbUMo2s/rn9X9R+WfN9v3YIwLGUbQErNaLly7HF27FSOH4UMAWr6pjisH8SE
|
798 |
+
-----END CERTIFICATE-----
|
799 |
+
|
800 |
+
America Online Root Certification Authority 1
|
801 |
+
=============================================
|
802 |
+
-----BEGIN CERTIFICATE-----
|
803 |
+
MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT
|
804 |
+
QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp
|
805 |
+
Y2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkG
|
806 |
+
A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg
|
807 |
+
T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQAD
|
808 |
+
ggEPADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lkhsmj76CG
|
809 |
+
v2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym1BW32J/X3HGrfpq/m44z
|
810 |
+
DyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsWOqMFf6Dch9Wc/HKpoH145LcxVR5lu9Rh
|
811 |
+
sCFg7RAycsWSJR74kEoYeEfffjA3PlAb2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP
|
812 |
+
8c9GsEsPPt2IYriMqQkoO3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0T
|
813 |
+
AQH/BAUwAwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAUAK3Z
|
814 |
+
o/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IBAQB8itEf
|
815 |
+
GDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkFZu90821fnZmv9ov761KyBZiibyrF
|
816 |
+
VL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAbLjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft
|
817 |
+
3OJvx8Fi8eNy1gTIdGcL+oiroQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43g
|
818 |
+
Kd8hdIaC2y+CMMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds
|
819 |
+
sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7
|
820 |
+
-----END CERTIFICATE-----
|
821 |
+
|
822 |
+
America Online Root Certification Authority 2
|
823 |
+
=============================================
|
824 |
+
-----BEGIN CERTIFICATE-----
|
825 |
+
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
|
850 |
+
cX/9XhmgD0uRuMRUvAawRY8mkaKO/qk=
|
851 |
+
-----END CERTIFICATE-----
|
852 |
+
|
853 |
+
Visa eCommerce Root
|
854 |
+
===================
|
855 |
+
-----BEGIN CERTIFICATE-----
|
856 |
+
MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQG
|
857 |
+
EwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2Ug
|
858 |
+
QXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2
|
859 |
+
WhcNMjIwNjI0MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMm
|
860 |
+
VmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv
|
861 |
+
bW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfL
|
862 |
+
F9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8b
|
863 |
+
RaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81q6UCzyr0
|
864 |
+
TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI
|
865 |
+
/k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzs
|
866 |
+
GHxBvfaLdXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG
|
867 |
+
MB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOCAQEAX/FBfXxc
|
868 |
+
CLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcRzCSs00Rsca4BIGsDoo8Ytyk6feUW
|
869 |
+
YFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pz
|
870 |
+
zkWKsKZJ/0x9nXGIxHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu
|
871 |
+
YQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt
|
872 |
+
398znM/jra6O1I7mT1GvFpLgXPYHDw==
|
873 |
+
-----END CERTIFICATE-----
|
874 |
+
|
875 |
+
Certum Root CA
|
876 |
+
==============
|
877 |
+
-----BEGIN CERTIFICATE-----
|
878 |
+
MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQK
|
879 |
+
ExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQTAeFw0wMjA2MTExMDQ2Mzla
|
880 |
+
Fw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8u
|
881 |
+
by4xEjAQBgNVBAMTCUNlcnR1bSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6x
|
882 |
+
wS7TT3zNJc4YPk/EjG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdL
|
883 |
+
kKWoePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GIULdtlkIJ
|
884 |
+
89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapuOb7kky/ZR6By6/qmW6/K
|
885 |
+
Uz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUgAKpoC6EahQGcxEZjgoi2IrHu/qpGWX7P
|
886 |
+
NSzVttpd90gzFFS269lvzs2I1qsb2pY7HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkq
|
887 |
+
hkiG9w0BAQUFAAOCAQEAuI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+
|
888 |
+
GXYkHAQaTOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTgxSvg
|
889 |
+
GrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1qCjqTE5s7FCMTY5w/
|
890 |
+
0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5xO/fIR/RpbxXyEV6DHpx8Uq79AtoS
|
891 |
+
qFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs6GAqm4VKQPNriiTsBhYscw==
|
892 |
+
-----END CERTIFICATE-----
|
893 |
+
|
894 |
+
Comodo AAA Services root
|
895 |
+
========================
|
896 |
+
-----BEGIN CERTIFICATE-----
|
897 |
+
MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS
|
898 |
+
R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg
|
899 |
+
TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw
|
900 |
+
MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl
|
901 |
+
c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV
|
902 |
+
BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
|
903 |
+
ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG
|
904 |
+
C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs
|
905 |
+
i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW
|
906 |
+
Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH
|
907 |
+
Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK
|
908 |
+
Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f
|
909 |
+
BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl
|
910 |
+
cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz
|
911 |
+
LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm
|
912 |
+
7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
|
913 |
+
Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z
|
914 |
+
8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C
|
915 |
+
12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
|
916 |
+
-----END CERTIFICATE-----
|
917 |
+
|
918 |
+
Comodo Secure Services root
|
919 |
+
===========================
|
920 |
+
-----BEGIN CERTIFICATE-----
|
921 |
+
MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS
|
922 |
+
R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg
|
923 |
+
TGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAw
|
924 |
+
MDAwMFoXDTI4MTIzMTIzNTk1OVowfjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFu
|
925 |
+
Y2hlc3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAi
|
926 |
+
BgNVBAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
927 |
+
ADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPMcm3ye5drswfxdySRXyWP
|
928 |
+
9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3SHpR7LZQdqnXXs5jLrLxkU0C8j6ysNstc
|
929 |
+
rbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rC
|
930 |
+
oznl2yY4rYsK7hljxxwk3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3V
|
931 |
+
p6ea5EQz6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNVHQ4E
|
932 |
+
FgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w
|
933 |
+
gYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL1NlY3VyZUNlcnRpZmlj
|
934 |
+
YXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRwOi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlm
|
935 |
+
aWNhdGVTZXJ2aWNlcy5jcmwwDQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm
|
936 |
+
4J4oqF7Tt/Q05qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj
|
937 |
+
Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtIgKvcnDe4IRRL
|
938 |
+
DXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJaD61JlfutuC23bkpgHl9j6Pw
|
939 |
+
pCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDlizeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1H
|
940 |
+
RR3B7Hzs/Sk=
|
941 |
+
-----END CERTIFICATE-----
|
942 |
+
|
943 |
+
Comodo Trusted Services root
|
944 |
+
============================
|
945 |
+
-----BEGIN CERTIFICATE-----
|
946 |
+
MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS
|
947 |
+
R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg
|
948 |
+
TGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEw
|
949 |
+
MDAwMDBaFw0yODEyMzEyMzU5NTlaMH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1h
|
950 |
+
bmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUw
|
951 |
+
IwYDVQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOC
|
952 |
+
AQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWWfnJSoBVC21ndZHoa0Lh7
|
953 |
+
3TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMtTGo87IvDktJTdyR0nAducPy9C1t2ul/y
|
954 |
+
/9c3S0pgePfw+spwtOpZqqPOSC+pw7ILfhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6
|
955 |
+
juljatEPmsbS9Is6FARW1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsS
|
956 |
+
ivnkBbA7kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0GA1Ud
|
957 |
+
DgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
|
958 |
+
/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21vZG9jYS5jb20vVHJ1c3RlZENlcnRp
|
959 |
+
ZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRodHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENl
|
960 |
+
cnRpZmljYXRlU2VydmljZXMuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8Ntw
|
961 |
+
uleGFTQQuS9/HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32
|
962 |
+
pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxISjBc/lDb+XbDA
|
963 |
+
BHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+xqFx7D+gIIxmOom0jtTYsU0l
|
964 |
+
R+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/AtyjcndBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O
|
965 |
+
9y5Xt5hwXsjEeLBi
|
966 |
+
-----END CERTIFICATE-----
|
967 |
+
|
968 |
+
QuoVadis Root CA
|
969 |
+
================
|
970 |
+
-----BEGIN CERTIFICATE-----
|
971 |
+
MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE
|
972 |
+
ChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
|
973 |
+
eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz
|
974 |
+
MTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp
|
975 |
+
cyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD
|
976 |
+
EyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF
|
977 |
+
AAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk
|
978 |
+
J0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL
|
979 |
+
F8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL
|
980 |
+
YzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen
|
981 |
+
AScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w
|
982 |
+
PQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y
|
983 |
+
ZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7
|
984 |
+
MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj
|
985 |
+
YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs
|
986 |
+
ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh
|
987 |
+
Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW
|
988 |
+
Fmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu
|
989 |
+
BgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw
|
990 |
+
FwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0
|
991 |
+
aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6
|
992 |
+
tlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo
|
993 |
+
fFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul
|
994 |
+
LsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x
|
995 |
+
gI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi
|
996 |
+
5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi
|
997 |
+
5nrQNiOKSnQ2+Q==
|
998 |
+
-----END CERTIFICATE-----
|
999 |
+
|
1000 |
+
QuoVadis Root CA 2
|
1001 |
+
==================
|
1002 |
+
-----BEGIN CERTIFICATE-----
|
1003 |
+
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
|
1029 |
+
-----END CERTIFICATE-----
|
1030 |
+
|
1031 |
+
QuoVadis Root CA 3
|
1032 |
+
==================
|
1033 |
+
-----BEGIN CERTIFICATE-----
|
1034 |
+
MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT
|
1035 |
+
EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx
|
1036 |
+
OTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
|
1037 |
+
aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC
|
1038 |
+
DwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg
|
1039 |
+
DhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij
|
1040 |
+
KTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K
|
1041 |
+
DDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv
|
1042 |
+
BNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp
|
1043 |
+
p5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8
|
1044 |
+
nT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX
|
1045 |
+
MJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM
|
1046 |
+
Gf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz
|
1047 |
+
uD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT
|
1048 |
+
BgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj
|
1049 |
+
YXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0
|
1050 |
+
aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB
|
1051 |
+
BQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD
|
1052 |
+
VR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4
|
1053 |
+
ywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE
|
1054 |
+
AxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV
|
1055 |
+
qyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s
|
1056 |
+
hvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z
|
1057 |
+
POuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2
|
1058 |
+
Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp
|
1059 |
+
8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC
|
1060 |
+
bjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu
|
1061 |
+
g/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p
|
1062 |
+
vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr
|
1063 |
+
qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto=
|
1064 |
+
-----END CERTIFICATE-----
|
1065 |
+
|
1066 |
+
Security Communication Root CA
|
1067 |
+
==============================
|
1068 |
+
-----BEGIN CERTIFICATE-----
|
1069 |
+
MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP
|
1070 |
+
U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw
|
1071 |
+
HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP
|
1072 |
+
U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw
|
1073 |
+
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw
|
1074 |
+
8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM
|
1075 |
+
DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX
|
1076 |
+
5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd
|
1077 |
+
DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2
|
1078 |
+
JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw
|
1079 |
+
DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g
|
1080 |
+
0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a
|
1081 |
+
mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ
|
1082 |
+
s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ
|
1083 |
+
6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi
|
1084 |
+
FL39vmwLAw==
|
1085 |
+
-----END CERTIFICATE-----
|
1086 |
+
|
1087 |
+
Sonera Class 1 Root CA
|
1088 |
+
======================
|
1089 |
+
-----BEGIN CERTIFICATE-----
|
1090 |
+
MIIDIDCCAgigAwIBAgIBJDANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG
|
1091 |
+
U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MxIENBMB4XDTAxMDQwNjEwNDkxM1oXDTIxMDQw
|
1092 |
+
NjEwNDkxM1owOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh
|
1093 |
+
IENsYXNzMSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALWJHytPZwp5/8Ue+H88
|
1094 |
+
7dF+2rDNbS82rDTG29lkFwhjMDMiikzujrsPDUJVyZ0upe/3p4zDq7mXy47vPxVnqIJyY1MPQYx9
|
1095 |
+
EJUkoVqlBvqSV536pQHydekfvFYmUk54GWVYVQNYwBSujHxVX3BbdyMGNpfzJLWaRpXk3w0LBUXl
|
1096 |
+
0fIdgrvGE+D+qnr9aTCU89JFhfzyMlsy3uhsXR/LpCJ0sICOXZT3BgBLqdReLjVQCfOAl/QMF645
|
1097 |
+
2F/NM8EcyonCIvdFEu1eEpOdY6uCLrnrQkFEy0oaAIINnvmLVz5MxxftLItyM19yejhW1ebZrgUa
|
1098 |
+
HXVFsculJRwSVzb9IjcCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQIR+IMi/ZT
|
1099 |
+
iFIwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQCLGrLJXWG04bkruVPRsoWdd44W7hE9
|
1100 |
+
28Jj2VuXZfsSZ9gqXLar5V7DtxYvyOirHYr9qxp81V9jz9yw3Xe5qObSIjiHBxTZ/75Wtf0HDjxV
|
1101 |
+
yhbMp6Z3N/vbXB9OWQaHowND9Rart4S9Tu+fMTfwRvFAttEMpWT4Y14h21VOTzF2nBBhjrZTOqMR
|
1102 |
+
vq9tfB69ri3iDGnHhVNoomG6xT60eVR4ngrHAr5i0RGCS2UvkVrCqIexVmiUefkl98HVrhq4uz2P
|
1103 |
+
qYo4Ffdz0Fpg0YCw8NzVUM1O7pJIae2yIx4wzMiUyLb1O4Z/P6Yun/Y+LLWSlj7fLJOK/4GMDw9Z
|
1104 |
+
IRlXvVWa
|
1105 |
+
-----END CERTIFICATE-----
|
1106 |
+
|
1107 |
+
Sonera Class 2 Root CA
|
1108 |
+
======================
|
1109 |
+
-----BEGIN CERTIFICATE-----
|
1110 |
+
MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG
|
1111 |
+
U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw
|
1112 |
+
NjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh
|
1113 |
+
IENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3
|
1114 |
+
/Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT
|
1115 |
+
dXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG
|
1116 |
+
f+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P
|
1117 |
+
tOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH
|
1118 |
+
nfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT
|
1119 |
+
XjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt
|
1120 |
+
0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI
|
1121 |
+
cbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph
|
1122 |
+
Oe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx
|
1123 |
+
EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH
|
1124 |
+
llpwrN9M
|
1125 |
+
-----END CERTIFICATE-----
|
1126 |
+
|
1127 |
+
Staat der Nederlanden Root CA
|
1128 |
+
=============================
|
1129 |
+
-----BEGIN CERTIFICATE-----
|
1130 |
+
MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJOTDEeMBwGA1UE
|
1131 |
+
ChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFhdCBkZXIgTmVkZXJsYW5kZW4g
|
1132 |
+
Um9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEyMTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4w
|
1133 |
+
HAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxh
|
1134 |
+
bmRlbiBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFt
|
1135 |
+
vsznExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw719tV2U02P
|
1136 |
+
jLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MOhXeiD+EwR+4A5zN9RGca
|
1137 |
+
C1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+UtFE5A3+y3qcym7RHjm+0Sq7lr7HcsBth
|
1138 |
+
vJly3uSJt3omXdozSVtSnA71iq3DuD3oBmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn6
|
1139 |
+
22r+I/q85Ej0ZytqERAhSQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRV
|
1140 |
+
HSAAMDwwOgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMvcm9v
|
1141 |
+
dC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA7Jbg0zTBLL9s+DAN
|
1142 |
+
BgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k/rvuFbQvBgwp8qiSpGEN/KtcCFtR
|
1143 |
+
EytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzmeafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbw
|
1144 |
+
MVcoEoJz6TMvplW0C5GUR5z6u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3y
|
1145 |
+
nGQI0DvDKcWy7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR
|
1146 |
+
iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw==
|
1147 |
+
-----END CERTIFICATE-----
|
1148 |
+
|
1149 |
+
TDC Internet Root CA
|
1150 |
+
====================
|
1151 |
+
-----BEGIN CERTIFICATE-----
|
1152 |
+
MIIEKzCCAxOgAwIBAgIEOsylTDANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJESzEVMBMGA1UE
|
1153 |
+
ChMMVERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTAeFw0wMTA0MDUx
|
1154 |
+
NjMzMTdaFw0yMTA0MDUxNzAzMTdaMEMxCzAJBgNVBAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJu
|
1155 |
+
ZXQxHTAbBgNVBAsTFFREQyBJbnRlcm5ldCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
|
1156 |
+
MIIBCgKCAQEAxLhAvJHVYx/XmaCLDEAedLdInUaMArLgJF/wGROnN4NrXceO+YQwzho7+vvOi20j
|
1157 |
+
xsNuZp+Jpd/gQlBn+h9sHvTQBda/ytZO5GhgbEaqHF1j4QeGDmUApy6mcca8uYGoOn0a0vnRrEvL
|
1158 |
+
znWv3Hv6gXPU/Lq9QYjUdLP5Xjg6PEOo0pVOd20TDJ2PeAG3WiAfAzc14izbSysseLlJ28TQx5yc
|
1159 |
+
5IogCSEWVmb/Bexb4/DPqyQkXsN/cHoSxNK1EKC2IeGNeGlVRGn1ypYcNIUXJXfi9i8nmHj9eQY6
|
1160 |
+
otZaQ8H/7AQ77hPv01ha/5Lr7K7a8jcDR0G2l8ktCkEiu7vmpwIDAQABo4IBJTCCASEwEQYJYIZI
|
1161 |
+
AYb4QgEBBAQDAgAHMGUGA1UdHwReMFwwWqBYoFakVDBSMQswCQYDVQQGEwJESzEVMBMGA1UEChMM
|
1162 |
+
VERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTENMAsGA1UEAxMEQ1JM
|
1163 |
+
MTArBgNVHRAEJDAigA8yMDAxMDQwNTE2MzMxN1qBDzIwMjEwNDA1MTcwMzE3WjALBgNVHQ8EBAMC
|
1164 |
+
AQYwHwYDVR0jBBgwFoAUbGQBx/2FbazI2p5QCIUItTxWqFAwHQYDVR0OBBYEFGxkAcf9hW2syNqe
|
1165 |
+
UAiFCLU8VqhQMAwGA1UdEwQFMAMBAf8wHQYJKoZIhvZ9B0EABBAwDhsIVjUuMDo0LjADAgSQMA0G
|
1166 |
+
CSqGSIb3DQEBBQUAA4IBAQBOQ8zR3R0QGwZ/t6T609lN+yOfI1Rb5osvBCiLtSdtiaHsmGnc540m
|
1167 |
+
gwV5dOy0uaOXwTUA/RXaOYE6lTGQ3pfphqiZdwzlWqCE/xIWrG64jcN7ksKsLtB9KOy282A4aW8+
|
1168 |
+
2ARVPp7MVdK6/rtHBNcK2RYKNCn1WBPVT8+PVkuzHu7TmHnaCB4Mb7j4Fifvwm899qNLPg7kbWzb
|
1169 |
+
O0ESm70NRyN/PErQr8Cv9u8btRXE64PECV90i9kR+8JWsTz4cMo0jUNAE4z9mQNUecYu6oah9jrU
|
1170 |
+
Cbz0vGbMPVjQV0kK7iXiQe4T+Zs4NNEA9X7nlB38aQNiuJkFBT1reBK9sG9l
|
1171 |
+
-----END CERTIFICATE-----
|
1172 |
+
|
1173 |
+
TDC OCES Root CA
|
1174 |
+
================
|
1175 |
+
-----BEGIN CERTIFICATE-----
|
1176 |
+
MIIFGTCCBAGgAwIBAgIEPki9xDANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJESzEMMAoGA1UE
|
1177 |
+
ChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTAeFw0wMzAyMTEwODM5MzBaFw0zNzAyMTEwOTA5
|
1178 |
+
MzBaMDExCzAJBgNVBAYTAkRLMQwwCgYDVQQKEwNUREMxFDASBgNVBAMTC1REQyBPQ0VTIENBMIIB
|
1179 |
+
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArGL2YSCyz8DGhdfjeebM7fI5kqSXLmSjhFuH
|
1180 |
+
nEz9pPPEXyG9VhDr2y5h7JNp46PMvZnDBfwGuMo2HP6QjklMxFaaL1a8z3sM8W9Hpg1DTeLpHTk0
|
1181 |
+
zY0s2RKY+ePhwUp8hjjEqcRhiNJerxomTdXkoCJHhNlktxmW/OwZ5LKXJk5KTMuPJItUGBxIYXvV
|
1182 |
+
iGjaXbXqzRowwYCDdlCqT9HU3Tjw7xb04QxQBr/q+3pJoSgrHPb8FTKjdGqPqcNiKXEx5TukYBde
|
1183 |
+
dObaE+3pHx8b0bJoc8YQNHVGEBDjkAB2QMuLt0MJIf+rTpPGWOmlgtt3xDqZsXKVSQTwtyv6e1mO
|
1184 |
+
3QIDAQABo4ICNzCCAjMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgewGA1UdIASB
|
1185 |
+
5DCB4TCB3gYIKoFQgSkBAQEwgdEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2VydGlmaWthdC5k
|
1186 |
+
ay9yZXBvc2l0b3J5MIGdBggrBgEFBQcCAjCBkDAKFgNUREMwAwIBARqBgUNlcnRpZmlrYXRlciBm
|
1187 |
+
cmEgZGVubmUgQ0EgdWRzdGVkZXMgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEuMS4xLiBDZXJ0aWZp
|
1188 |
+
Y2F0ZXMgZnJvbSB0aGlzIENBIGFyZSBpc3N1ZWQgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEuMS4x
|
1189 |
+
LjARBglghkgBhvhCAQEEBAMCAAcwgYEGA1UdHwR6MHgwSKBGoESkQjBAMQswCQYDVQQGEwJESzEM
|
1190 |
+
MAoGA1UEChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTENMAsGA1UEAxMEQ1JMMTAsoCqgKIYm
|
1191 |
+
aHR0cDovL2NybC5vY2VzLmNlcnRpZmlrYXQuZGsvb2Nlcy5jcmwwKwYDVR0QBCQwIoAPMjAwMzAy
|
1192 |
+
MTEwODM5MzBagQ8yMDM3MDIxMTA5MDkzMFowHwYDVR0jBBgwFoAUYLWF7FZkfhIZJ2cdUBVLc647
|
1193 |
+
+RIwHQYDVR0OBBYEFGC1hexWZH4SGSdnHVAVS3OuO/kSMB0GCSqGSIb2fQdBAAQQMA4bCFY2LjA6
|
1194 |
+
NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEACromJkbTc6gJ82sLMJn9iuFXehHTuJTXCRBuo7E4
|
1195 |
+
A9G28kNBKWKnctj7fAXmMXAnVBhOinxO5dHKjHiIzxvTkIvmI/gLDjNDfZziChmPyQE+dF10yYsc
|
1196 |
+
A+UYyAFMP8uXBV2YcaaYb7Z8vTd/vuGTJW1v8AqtFxjhA7wHKcitJuj4YfD9IQl+mo6paH1IYnK9
|
1197 |
+
AOoBmbgGglGBTvH1tJFUuSN6AJqfXY3gPGS5GhKSKseCRHI53OI8xthV9RVOyAUO28bQYqbsFbS1
|
1198 |
+
AoLbrIyigfCbmTH1ICCoiGEKB5+U/NDXG8wuF/MEJ3Zn61SD/aSQfgY9BKNDLdr8C2LqL19iUw==
|
1199 |
+
-----END CERTIFICATE-----
|
1200 |
+
|
1201 |
+
UTN DATACorp SGC Root CA
|
1202 |
+
========================
|
1203 |
+
-----BEGIN CERTIFICATE-----
|
1204 |
+
MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UE
|
1205 |
+
BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
|
1206 |
+
IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZ
|
1207 |
+
BgNVBAMTElVUTiAtIERBVEFDb3JwIFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBa
|
1208 |
+
MIGTMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4w
|
1209 |
+
HAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRy
|
1210 |
+
dXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjANBgkqhkiG9w0BAQEFAAOC
|
1211 |
+
AQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ys
|
1212 |
+
raP6LnD43m77VkIVni5c7yPeIbkFdicZD0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlo
|
1213 |
+
wHDyUwDAXlCCpVZvNvlK4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA
|
1214 |
+
9P4yPykqlXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulWbfXv
|
1215 |
+
33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQABo4GrMIGoMAsGA1Ud
|
1216 |
+
DwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRTMtGzz3/64PGgXYVOktKeRR20TzA9
|
1217 |
+
BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dD
|
1218 |
+
LmNybDAqBgNVHSUEIzAhBggrBgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3
|
1219 |
+
DQEBBQUAA4IBAQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft
|
1220 |
+
Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyjj98C5OBxOvG0
|
1221 |
+
I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVHKWss5nbZqSl9Mt3JNjy9rjXx
|
1222 |
+
EZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwP
|
1223 |
+
DPafepE39peC4N1xaf92P2BNPM/3mfnGV/TJVTl4uix5yaaIK/QI
|
1224 |
+
-----END CERTIFICATE-----
|
1225 |
+
|
1226 |
+
UTN USERFirst Email Root CA
|
1227 |
+
===========================
|
1228 |
+
-----BEGIN CERTIFICATE-----
|
1229 |
+
MIIEojCCA4qgAwIBAgIQRL4Mi1AAJLQR0zYlJWfJiTANBgkqhkiG9w0BAQUFADCBrjELMAkGA1UE
|
1230 |
+
BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
|
1231 |
+
IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xNjA0
|
1232 |
+
BgNVBAMTLVVUTi1VU0VSRmlyc3QtQ2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBFbWFpbDAeFw05
|
1233 |
+
OTA3MDkxNzI4NTBaFw0xOTA3MDkxNzM2NThaMIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQx
|
1234 |
+
FzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsx
|
1235 |
+
ITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UEAxMtVVROLVVTRVJGaXJz
|
1236 |
+
dC1DbGllbnQgQXV0aGVudGljYXRpb24gYW5kIEVtYWlsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
|
1237 |
+
MIIBCgKCAQEAsjmFpPJ9q0E7YkY3rs3BYHW8OWX5ShpHornMSMxqmNVNNRm5pELlzkniii8efNIx
|
1238 |
+
B8dOtINknS4p1aJkxIW9hVE1eaROaJB7HHqkkqgX8pgV8pPMyaQylbsMTzC9mKALi+VuG6JG+ni8
|
1239 |
+
om+rWV6lL8/K2m2qL+usobNqqrcuZzWLeeEeaYji5kbNoKXqvgvOdjp6Dpvq/NonWz1zHyLmSGHG
|
1240 |
+
TPNpsaguG7bUMSAsvIKKjqQOpdeJQ/wWWq8dcdcRWdq6hw2v+vPhwvCkxWeM1tZUOt4KpLoDd7Nl
|
1241 |
+
yP0e03RiqhjKaJMeoYV+9Udly/hNVyh00jT/MLbu9mIwFIws6wIDAQABo4G5MIG2MAsGA1UdDwQE
|
1242 |
+
AwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSJgmd9xJ0mcABLtFBIfN49rgRufTBYBgNV
|
1243 |
+
HR8EUTBPME2gS6BJhkdodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLVVTRVJGaXJzdC1DbGll
|
1244 |
+
bnRBdXRoZW50aWNhdGlvbmFuZEVtYWlsLmNybDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH
|
1245 |
+
AwQwDQYJKoZIhvcNAQEFBQADggEBALFtYV2mGn98q0rkMPxTbyUkxsrt4jFcKw7u7mFVbwQ+zzne
|
1246 |
+
xRtJlOTrIEy05p5QLnLZjfWqo7NK2lYcYJeA3IKirUq9iiv/Cwm0xtcgBEXkzYABurorbs6q15L+
|
1247 |
+
5K/r9CYdFip/bDCVNy8zEqx/3cfREYxRmLLQo5HQrfafnoOTHh1CuEava2bwm3/q4wMC5QJRwarV
|
1248 |
+
NZ1yQAOJujEdxRBoUp7fooXFXAimeOZTT7Hot9MUnpOmw2TjrH5xzbyf6QMbzPvprDHBr3wVdAKZ
|
1249 |
+
w7JHpsIyYdfHb0gkUSeh1YdV8nuPmD0Wnu51tvjQjvLzxq4oW6fw8zYX/MMF08oDSlQ=
|
1250 |
+
-----END CERTIFICATE-----
|
1251 |
+
|
1252 |
+
UTN USERFirst Hardware Root CA
|
1253 |
+
==============================
|
1254 |
+
-----BEGIN CERTIFICATE-----
|
1255 |
+
MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UE
|
1256 |
+
BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
|
1257 |
+
IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAd
|
1258 |
+
BgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgx
|
1259 |
+
OTIyWjCBlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0
|
1260 |
+
eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVz
|
1261 |
+
ZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwggEiMA0GCSqGSIb3
|
1262 |
+
DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlI
|
1263 |
+
wrthdBKWHTxqctU8EGc6Oe0rE81m65UJM6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFd
|
1264 |
+
tqdt++BxF2uiiPsA3/4aMXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8
|
1265 |
+
i4fDidNdoI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqIDsjf
|
1266 |
+
Pe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9KsyoUhbAgMBAAGjgbkw
|
1267 |
+
gbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFKFyXyYbKJhDlV0HN9WF
|
1268 |
+
lp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNF
|
1269 |
+
UkZpcnN0LUhhcmR3YXJlLmNybDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUF
|
1270 |
+
BwMGBggrBgEFBQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM
|
1271 |
+
//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28GpgoiskliCE7/yMgUsogW
|
1272 |
+
XecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gECJChicsZUN/KHAG8HQQZexB2
|
1273 |
+
lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kn
|
1274 |
+
iCrVWFCVH/A7HFe7fRQ5YiuayZSSKqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67
|
1275 |
+
nfhmqA==
|
1276 |
+
-----END CERTIFICATE-----
|
1277 |
+
|
1278 |
+
UTN USERFirst Object Root CA
|
1279 |
+
============================
|
1280 |
+
-----BEGIN CERTIFICATE-----
|
1281 |
+
MIIEZjCCA06gAwIBAgIQRL4Mi1AAJLQR0zYt4LNfGzANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UE
|
1282 |
+
BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
|
1283 |
+
IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHTAb
|
1284 |
+
BgNVBAMTFFVUTi1VU0VSRmlyc3QtT2JqZWN0MB4XDTk5MDcwOTE4MzEyMFoXDTE5MDcwOTE4NDAz
|
1285 |
+
NlowgZUxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkx
|
1286 |
+
HjAcBgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEhMB8GA1UECxMYaHR0cDovL3d3dy51c2Vy
|
1287 |
+
dHJ1c3QuY29tMR0wGwYDVQQDExRVVE4tVVNFUkZpcnN0LU9iamVjdDCCASIwDQYJKoZIhvcNAQEB
|
1288 |
+
BQADggEPADCCAQoCggEBAM6qgT+jo2F4qjEAVZURnicPHxzfOpuCaDDASmEd8S8O+r5596Uj71VR
|
1289 |
+
loTN2+O5bj4x2AogZ8f02b+U60cEPgLOKqJdhwQJ9jCdGIqXsqoc/EHSoTbL+z2RuufZcDX65OeQ
|
1290 |
+
w5ujm9M89RKZd7G3CeBo5hy485RjiGpq/gt2yb70IuRnuasaXnfBhQfdDWy/7gbHd2pBnqcP1/vu
|
1291 |
+
lBe3/IW+pKvEHDHd17bR5PDv3xaPslKT16HUiaEHLr/hARJCHhrh2JU022R5KP+6LhHC5ehbkkj7
|
1292 |
+
RwvCbNqtMoNB86XlQXD9ZZBt+vpRxPm9lisZBCzTbafc8H9vg2XiaquHhnUCAwEAAaOBrzCBrDAL
|
1293 |
+
BgNVHQ8EBAMCAcYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU2u1kdBScFDyr3ZmpvVsoTYs8
|
1294 |
+
ydgwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmly
|
1295 |
+
c3QtT2JqZWN0LmNybDApBgNVHSUEIjAgBggrBgEFBQcDAwYIKwYBBQUHAwgGCisGAQQBgjcKAwQw
|
1296 |
+
DQYJKoZIhvcNAQEFBQADggEBAAgfUrE3RHjb/c652pWWmKpVZIC1WkDdIaXFwfNfLEzIR1pp6ujw
|
1297 |
+
NTX00CXzyKakh0q9G7FzCL3Uw8q2NbtZhncxzaeAFK4T7/yxSPlrJSUtUbYsbUXBmMiKVl0+7kNO
|
1298 |
+
PmsnjtA6S4ULX9Ptaqd1y9Fahy85dRNacrACgZ++8A+EVCBibGnU4U3GDZlDAQ0Slox4nb9QorFE
|
1299 |
+
qmrPF3rPbw/U+CRVX/A0FklmPlBGyWNxODFiuGK581OtbLUrohKqGU8J2l7nk8aOFAj+8DCAGKCG
|
1300 |
+
hU3IfdeLA/5u1fedFqySLKAj5ZyRUh+U3xeUc8OzwcFxBSAAeL0TUh2oPs0AH8g=
|
1301 |
+
-----END CERTIFICATE-----
|
1302 |
+
|
1303 |
+
Camerfirma Chambers of Commerce Root
|
1304 |
+
====================================
|
1305 |
+
-----BEGIN CERTIFICATE-----
|
1306 |
+
MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe
|
1307 |
+
QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i
|
1308 |
+
ZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAx
|
1309 |
+
NjEzNDNaFw0zNzA5MzAxNjEzNDRaMH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZp
|
1310 |
+
cm1hIFNBIENJRiBBODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3Jn
|
1311 |
+
MSIwIAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0BAQEFAAOC
|
1312 |
+
AQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtbunXF/KGIJPov7coISjlU
|
1313 |
+
xFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0dBmpAPrMMhe5cG3nCYsS4No41XQEMIwRH
|
1314 |
+
NaqbYE6gZj3LJgqcQKH0XZi/caulAGgq7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jW
|
1315 |
+
DA+wWFjbw2Y3npuRVDM30pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFV
|
1316 |
+
d9oKDMyXroDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIGA1Ud
|
1317 |
+
EwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5jaGFtYmVyc2lnbi5v
|
1318 |
+
cmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p26EpW1eLTXYGduHRooowDgYDVR0P
|
1319 |
+
AQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hh
|
1320 |
+
bWJlcnNpZ24ub3JnMCcGA1UdEgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYD
|
1321 |
+
VR0gBFEwTzBNBgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz
|
1322 |
+
aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEBAAxBl8IahsAi
|
1323 |
+
fJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZdp0AJPaxJRUXcLo0waLIJuvvD
|
1324 |
+
L8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wN
|
1325 |
+
UPf6s+xCX6ndbcj0dc97wXImsQEcXCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/n
|
1326 |
+
ADydb47kMgkdTXg0eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1
|
1327 |
+
erfutGWaIZDgqtCYvDi1czyL+Nw=
|
1328 |
+
-----END CERTIFICATE-----
|
1329 |
+
|
1330 |
+
Camerfirma Global Chambersign Root
|
1331 |
+
==================================
|
1332 |
+
-----BEGIN CERTIFICATE-----
|
1333 |
+
MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe
|
1334 |
+
QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i
|
1335 |
+
ZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYx
|
1336 |
+
NDE4WhcNMzcwOTMwMTYxNDE4WjB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJt
|
1337 |
+
YSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEg
|
1338 |
+
MB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUAA4IBDQAw
|
1339 |
+
ggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0Mi+ITaFgCPS3CU6gSS9J
|
1340 |
+
1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/sQJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8O
|
1341 |
+
by4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpVeAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl
|
1342 |
+
6DJWk0aJqCWKZQbua795B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c
|
1343 |
+
8lCrEqWhz0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0TAQH/
|
1344 |
+
BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1iZXJzaWduLm9yZy9j
|
1345 |
+
aGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4wTcbOX60Qq+UDpfqpFDAOBgNVHQ8B
|
1346 |
+
Af8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAHMCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBj
|
1347 |
+
aGFtYmVyc2lnbi5vcmcwKgYDVR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9y
|
1348 |
+
ZzBbBgNVHSAEVDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh
|
1349 |
+
bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0BAQUFAAOCAQEA
|
1350 |
+
PDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUMbKGKfKX0j//U2K0X1S0E0T9Y
|
1351 |
+
gOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXiryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJ
|
1352 |
+
PJ7oKXqJ1/6v/2j1pReQvayZzKWGVwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4
|
1353 |
+
IBHNfTIzSJRUTN3cecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREes
|
1354 |
+
t2d/AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A==
|
1355 |
+
-----END CERTIFICATE-----
|
1356 |
+
|
1357 |
+
NetLock Qualified (Class QA) Root
|
1358 |
+
=================================
|
1359 |
+
-----BEGIN CERTIFICATE-----
|
1360 |
+
MIIG0TCCBbmgAwIBAgIBezANBgkqhkiG9w0BAQUFADCByTELMAkGA1UEBhMCSFUxETAPBgNVBAcT
|
1361 |
+
CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV
|
1362 |
+
BAsTEVRhbnVzaXR2YW55a2lhZG9rMUIwQAYDVQQDEzlOZXRMb2NrIE1pbm9zaXRldHQgS296amVn
|
1363 |
+
eXpvaSAoQ2xhc3MgUUEpIFRhbnVzaXR2YW55a2lhZG8xHjAcBgkqhkiG9w0BCQEWD2luZm9AbmV0
|
1364 |
+
bG9jay5odTAeFw0wMzAzMzAwMTQ3MTFaFw0yMjEyMTUwMTQ3MTFaMIHJMQswCQYDVQQGEwJIVTER
|
1365 |
+
MA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNhZ2kgS2Z0
|
1366 |
+
LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxQjBABgNVBAMTOU5ldExvY2sgTWlub3NpdGV0
|
1367 |
+
dCBLb3pqZWd5em9pIChDbGFzcyBRQSkgVGFudXNpdHZhbnlraWFkbzEeMBwGCSqGSIb3DQEJARYP
|
1368 |
+
aW5mb0BuZXRsb2NrLmh1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx1Ilstg91IRV
|
1369 |
+
CacbvWy5FPSKAtt2/GoqeKvld/Bu4IwjZ9ulZJm53QE+b+8tmjwi8F3JV6BVQX/yQ15YglMxZc4e
|
1370 |
+
8ia6AFQer7C8HORSjKAyr7c3sVNnaHRnUPYtLmTeriZ539+Zhqurf4XsoPuAzPS4DB6TRWO53Lhb
|
1371 |
+
m+1bOdRfYrCnjnxmOCyqsQhjF2d9zL2z8cM/z1A57dEZgxXbhxInlrfa6uWdvLrqOU+L73Sa58XQ
|
1372 |
+
0uqGURzk/mQIKAR5BevKxXEOC++r6uwSEaEYBTJp0QwsGj0lmT+1fMptsK6ZmfoIYOcZwvK9UdPM
|
1373 |
+
0wKswREMgM6r3JSda6M5UzrWhQIDAMV9o4ICwDCCArwwEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNV
|
1374 |
+
HQ8BAf8EBAMCAQYwggJ1BglghkgBhvhCAQ0EggJmFoICYkZJR1lFTEVNISBFemVuIHRhbnVzaXR2
|
1375 |
+
YW55IGEgTmV0TG9jayBLZnQuIE1pbm9zaXRldHQgU3pvbGdhbHRhdGFzaSBTemFiYWx5emF0YWJh
|
1376 |
+
biBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBBIG1pbm9zaXRldHQgZWxla3Ryb25p
|
1377 |
+
a3VzIGFsYWlyYXMgam9naGF0YXMgZXJ2ZW55ZXN1bGVzZW5laywgdmFsYW1pbnQgZWxmb2dhZGFz
|
1378 |
+
YW5hayBmZWx0ZXRlbGUgYSBNaW5vc2l0ZXR0IFN6b2xnYWx0YXRhc2kgU3phYmFseXphdGJhbiwg
|
1379 |
+
YXogQWx0YWxhbm9zIFN6ZXJ6b2Rlc2kgRmVsdGV0ZWxla2JlbiBlbG9pcnQgZWxsZW5vcnplc2kg
|
1380 |
+
ZWxqYXJhcyBtZWd0ZXRlbGUuIEEgZG9rdW1lbnR1bW9rIG1lZ3RhbGFsaGF0b2sgYSBodHRwczov
|
1381 |
+
L3d3dy5uZXRsb2NrLmh1L2RvY3MvIGNpbWVuIHZhZ3kga2VyaGV0b2sgYXogaW5mb0BuZXRsb2Nr
|
1382 |
+
Lm5ldCBlLW1haWwgY2ltZW4uIFdBUk5JTkchIFRoZSBpc3N1YW5jZSBhbmQgdGhlIHVzZSBvZiB0
|
1383 |
+
aGlzIGNlcnRpZmljYXRlIGFyZSBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIFF1YWxpZmllZCBDUFMg
|
1384 |
+
YXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3Lm5ldGxvY2suaHUvZG9jcy8gb3IgYnkgZS1tYWlsIGF0
|
1385 |
+
IGluZm9AbmV0bG9jay5uZXQwHQYDVR0OBBYEFAlqYhaSsFq7VQ7LdTI6MuWyIckoMA0GCSqGSIb3
|
1386 |
+
DQEBBQUAA4IBAQCRalCc23iBmz+LQuM7/KbD7kPgz/PigDVJRXYC4uMvBcXxKufAQTPGtpvQMznN
|
1387 |
+
wNuhrWw3AkxYQTvyl5LGSKjN5Yo5iWH5Upfpvfb5lHTocQ68d4bDBsxafEp+NFAwLvt/MpqNPfMg
|
1388 |
+
W/hqyobzMUwsWYACff44yTB1HLdV47yfuqhthCgFdbOLDcCRVCHnpgu0mfVRQdzNo0ci2ccBgcTc
|
1389 |
+
R08m6h/t280NmPSjnLRzMkqWmf68f8glWPhY83ZmiVSkpj7EUFy6iRiCdUgh0k8T6GB+B3bbELVR
|
1390 |
+
5qq5aKrN9p2QdRLqOBrKROi3macqaJVmlaut74nLYKkGEsaUR+ko
|
1391 |
+
-----END CERTIFICATE-----
|
1392 |
+
|
1393 |
+
NetLock Notary (Class A) Root
|
1394 |
+
=============================
|
1395 |
+
-----BEGIN CERTIFICATE-----
|
1396 |
+
MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQI
|
1397 |
+
EwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6
|
1398 |
+
dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9j
|
1399 |
+
ayBLb3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oX
|
1400 |
+
DTE5MDIxOTIzMTQ0N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQH
|
1401 |
+
EwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYD
|
1402 |
+
VQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFz
|
1403 |
+
cyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSM
|
1404 |
+
D7tM9DceqQWC2ObhbHDqeLVu0ThEDaiDzl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZ
|
1405 |
+
z+qMkjvN9wfcZnSX9EUi3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC
|
1406 |
+
/tmwqcm8WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LYOph7
|
1407 |
+
tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2EsiNCubMvJIH5+hCoR6
|
1408 |
+
4sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCCApswDgYDVR0PAQH/BAQDAgAGMBIG
|
1409 |
+
A1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaC
|
1410 |
+
Ak1GSUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pv
|
1411 |
+
bGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu
|
1412 |
+
IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2Vn
|
1413 |
+
LWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0
|
1414 |
+
ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFz
|
1415 |
+
IGxlaXJhc2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBh
|
1416 |
+
IGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVu
|
1417 |
+
b3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBh
|
1418 |
+
bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sg
|
1419 |
+
Q1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFp
|
1420 |
+
bCBhdCBjcHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5
|
1421 |
+
ayZrU3/b39/zcT0mwBQOxmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjP
|
1422 |
+
ytoUMaFP0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQQeJB
|
1423 |
+
CWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxkf1qbFFgBJ34TUMdr
|
1424 |
+
KuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK8CtmdWOMovsEPoMOmzbwGOQmIMOM
|
1425 |
+
8CgHrTwXZoi1/baI
|
1426 |
+
-----END CERTIFICATE-----
|
1427 |
+
|
1428 |
+
NetLock Business (Class B) Root
|
1429 |
+
===============================
|
1430 |
+
-----BEGIN CERTIFICATE-----
|
1431 |
+
MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUxETAPBgNVBAcT
|
1432 |
+
CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV
|
1433 |
+
BAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQDEylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikg
|
1434 |
+
VGFudXNpdHZhbnlraWFkbzAeFw05OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYD
|
1435 |
+
VQQGEwJIVTERMA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRv
|
1436 |
+
bnNhZ2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5ldExvY2sg
|
1437 |
+
VXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
|
1438 |
+
iQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xKgZjupNTKihe5In+DCnVMm8Bp2GQ5o+2S
|
1439 |
+
o/1bXHQawEfKOml2mrriRBf8TKPV/riXiK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr
|
1440 |
+
1nGTLbO/CVRY7QbrqHvcQ7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNV
|
1441 |
+
HQ8BAf8EBAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZ
|
1442 |
+
RUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRh
|
1443 |
+
dGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQuIEEgaGl0
|
1444 |
+
ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRv
|
1445 |
+
c2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUg
|
1446 |
+
YXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh
|
1447 |
+
c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBz
|
1448 |
+
Oi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6ZXNA
|
1449 |
+
bmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhl
|
1450 |
+
IHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2
|
1451 |
+
YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBj
|
1452 |
+
cHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06sPgzTEdM
|
1453 |
+
43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXan3BukxowOR0w2y7jfLKR
|
1454 |
+
stE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKSNitjrFgBazMpUIaD8QFI
|
1455 |
+
-----END CERTIFICATE-----
|
1456 |
+
|
1457 |
+
NetLock Express (Class C) Root
|
1458 |
+
==============================
|
1459 |
+
-----BEGIN CERTIFICATE-----
|
1460 |
+
MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUxETAPBgNVBAcT
|
1461 |
+
CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV
|
1462 |
+
BAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQDEytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBD
|
1463 |
+
KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJ
|
1464 |
+
BgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6
|
1465 |
+
dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMrTmV0TG9j
|
1466 |
+
ayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzANBgkqhkiG9w0BAQEFAAOB
|
1467 |
+
jQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNAOoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3Z
|
1468 |
+
W3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63
|
1469 |
+
euyucYT2BDMIJTLrdKwWRMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQw
|
1470 |
+
DgYDVR0PAQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEWggJN
|
1471 |
+
RklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0YWxhbm9zIFN6b2xn
|
1472 |
+
YWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBB
|
1473 |
+
IGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBOZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1i
|
1474 |
+
aXp0b3NpdGFzYSB2ZWRpLiBBIGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0
|
1475 |
+
ZWxlIGF6IGVsb2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs
|
1476 |
+
ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25sYXBqYW4gYSBo
|
1477 |
+
dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kga2VyaGV0byBheiBlbGxlbm9y
|
1478 |
+
emVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4gSU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5k
|
1479 |
+
IHRoZSB1c2Ugb2YgdGhpcyBjZXJ0aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQ
|
1480 |
+
UyBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwg
|
1481 |
+
YXQgY3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmYta3UzbM2
|
1482 |
+
xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2gpO0u9f38vf5NNwgMvOOW
|
1483 |
+
gyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4Fp1hBWeAyNDYpQcCNJgEjTME1A==
|
1484 |
+
-----END CERTIFICATE-----
|
1485 |
+
|
1486 |
+
XRamp Global CA Root
|
1487 |
+
====================
|
1488 |
+
-----BEGIN CERTIFICATE-----
|
1489 |
+
MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE
|
1490 |
+
BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj
|
1491 |
+
dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
|
1492 |
+
dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx
|
1493 |
+
HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg
|
1494 |
+
U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
|
1495 |
+
dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu
|
1496 |
+
IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx
|
1497 |
+
foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE
|
1498 |
+
zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs
|
1499 |
+
AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry
|
1500 |
+
xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud
|
1501 |
+
EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap
|
1502 |
+
oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC
|
1503 |
+
AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc
|
1504 |
+
/Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
|
1505 |
+
qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n
|
1506 |
+
nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz
|
1507 |
+
8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw=
|
1508 |
+
-----END CERTIFICATE-----
|
1509 |
+
|
1510 |
+
Go Daddy Class 2 CA
|
1511 |
+
===================
|
1512 |
+
-----BEGIN CERTIFICATE-----
|
1513 |
+
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY
|
1514 |
+
VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp
|
1515 |
+
ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG
|
1516 |
+
A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g
|
1517 |
+
RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD
|
1518 |
+
ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv
|
1519 |
+
2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32
|
1520 |
+
qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j
|
1521 |
+
YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY
|
1522 |
+
vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O
|
1523 |
+
BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o
|
1524 |
+
atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu
|
1525 |
+
MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG
|
1526 |
+
A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim
|
1527 |
+
PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt
|
1528 |
+
I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
|
1529 |
+
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI
|
1530 |
+
Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b
|
1531 |
+
vZ8=
|
1532 |
+
-----END CERTIFICATE-----
|
1533 |
+
|
1534 |
+
Starfield Class 2 CA
|
1535 |
+
====================
|
1536 |
+
-----BEGIN CERTIFICATE-----
|
1537 |
+
MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc
|
1538 |
+
U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg
|
1539 |
+
Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo
|
1540 |
+
MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG
|
1541 |
+
A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG
|
1542 |
+
SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY
|
1543 |
+
bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ
|
1544 |
+
JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm
|
1545 |
+
epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN
|
1546 |
+
F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF
|
1547 |
+
MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f
|
1548 |
+
hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo
|
1549 |
+
bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g
|
1550 |
+
QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs
|
1551 |
+
afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM
|
1552 |
+
PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
|
1553 |
+
xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD
|
1554 |
+
KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3
|
1555 |
+
QBFGmh95DmK/D5fs4C8fF5Q=
|
1556 |
+
-----END CERTIFICATE-----
|
1557 |
+
|
1558 |
+
StartCom Certification Authority
|
1559 |
+
================================
|
1560 |
+
-----BEGIN CERTIFICATE-----
|
1561 |
+
MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN
|
1562 |
+
U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu
|
1563 |
+
ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0
|
1564 |
+
NjM2WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk
|
1565 |
+
LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg
|
1566 |
+
U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
|
1567 |
+
ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y
|
1568 |
+
o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/
|
1569 |
+
Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d
|
1570 |
+
eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt
|
1571 |
+
2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z
|
1572 |
+
6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ
|
1573 |
+
osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/
|
1574 |
+
untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc
|
1575 |
+
UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT
|
1576 |
+
37uMdBNSSwIDAQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE
|
1577 |
+
FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9jZXJ0LnN0YXJ0
|
1578 |
+
Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3JsLnN0YXJ0Y29tLm9yZy9zZnNj
|
1579 |
+
YS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFMBgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUH
|
1580 |
+
AgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRw
|
1581 |
+
Oi8vY2VydC5zdGFydGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYg
|
1582 |
+
U3RhcnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlhYmlsaXR5
|
1583 |
+
LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2YgdGhlIFN0YXJ0Q29tIENl
|
1584 |
+
cnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFpbGFibGUgYXQgaHR0cDovL2NlcnQuc3Rh
|
1585 |
+
cnRjb20ub3JnL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilT
|
1586 |
+
dGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOC
|
1587 |
+
AgEAFmyZ9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8jhvh
|
1588 |
+
3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUWFjgKXlf2Ysd6AgXm
|
1589 |
+
vB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJzewT4F+irsfMuXGRuczE6Eri8sxHk
|
1590 |
+
fY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3
|
1591 |
+
fsNrarnDy0RLrHiQi+fHLB5LEUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZ
|
1592 |
+
EoalHmdkrQYuL6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq
|
1593 |
+
yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuCO3NJo2pXh5Tl
|
1594 |
+
1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6Vum0ABj6y6koQOdjQK/W/7HW/
|
1595 |
+
lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkyShNOsF/5oirpt9P/FlUQqmMGqz9IgcgA38coro
|
1596 |
+
g14=
|
1597 |
+
-----END CERTIFICATE-----
|
1598 |
+
|
1599 |
+
Taiwan GRCA
|
1600 |
+
===========
|
1601 |
+
-----BEGIN CERTIFICATE-----
|
1602 |
+
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
|
1627 |
+
-----END CERTIFICATE-----
|
1628 |
+
|
1629 |
+
Firmaprofesional Root CA
|
1630 |
+
========================
|
1631 |
+
-----BEGIN CERTIFICATE-----
|
1632 |
+
MIIEVzCCAz+gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnTELMAkGA1UEBhMCRVMxIjAgBgNVBAcT
|
1633 |
+
GUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1dG9yaWRhZCBkZSBDZXJ0aWZp
|
1634 |
+
Y2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FA
|
1635 |
+
ZmlybWFwcm9mZXNpb25hbC5jb20wHhcNMDExMDI0MjIwMDAwWhcNMTMxMDI0MjIwMDAwWjCBnTEL
|
1636 |
+
MAkGA1UEBhMCRVMxIjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMT
|
1637 |
+
OUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2
|
1638 |
+
ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20wggEiMA0GCSqGSIb3DQEB
|
1639 |
+
AQUAA4IBDwAwggEKAoIBAQDnIwNvbyOlXnjOlSztlB5uCp4Bx+ow0Syd3Tfom5h5VtP8c9/Qit5V
|
1640 |
+
j1H5WuretXDE7aTt/6MNbg9kUDGvASdYrv5sp0ovFy3Tc9UTHI9ZpTQsHVQERc1ouKDAA6XPhUJH
|
1641 |
+
lShbz++AbOCQl4oBPB3zhxAwJkh91/zpnZFx/0GaqUC1N5wpIE8fUuOgfRNtVLcK3ulqTgesrBlf
|
1642 |
+
3H5idPayBQC6haD9HThuy1q7hryUZzM1gywfI834yJFxzJeL764P3CkDG8A563DtwW4O2GcLiam8
|
1643 |
+
NeTvtjS0pbbELaW+0MOUJEjb35bTALVmGotmBQ/dPz/LP6pemkr4tErvlTcbAgMBAAGjgZ8wgZww
|
1644 |
+
KgYDVR0RBCMwIYYfaHR0cDovL3d3dy5maXJtYXByb2Zlc2lvbmFsLmNvbTASBgNVHRMBAf8ECDAG
|
1645 |
+
AQH/AgEBMCsGA1UdEAQkMCKADzIwMDExMDI0MjIwMDAwWoEPMjAxMzEwMjQyMjAwMDBaMA4GA1Ud
|
1646 |
+
DwEB/wQEAwIBBjAdBgNVHQ4EFgQUMwugZtHq2s7eYpMEKFK1FH84aLcwDQYJKoZIhvcNAQEFBQAD
|
1647 |
+
ggEBAEdz/o0nVPD11HecJ3lXV7cVVuzH2Fi3AQL0M+2TUIiefEaxvT8Ub/GzR0iLjJcG1+p+o1wq
|
1648 |
+
u00vR+L4OQbJnC4xGgN49Lw4xiKLMzHwFgQEffl25EvXwOaD7FnMP97/T2u3Z36mhoEyIwOdyPdf
|
1649 |
+
wUpgpZKpsaSgYMN4h7Mi8yrrW6ntBas3D7Hi05V2Y1Z0jFhyGzflZKG+TQyTmAyX9odtsz/ny4Cm
|
1650 |
+
7YjHX1BiAuiZdBbQ5rQ58SfLyEDW44YQqSMSkuBpQWOnryULwMWSyx6Yo1q6xTMPoJcB3X/ge9YG
|
1651 |
+
VM+h4k0460tQtcsm9MracEpqoeJ5quGnM/b9Sh/22WA=
|
1652 |
+
-----END CERTIFICATE-----
|
1653 |
+
|
1654 |
+
Wells Fargo Root CA
|
1655 |
+
===================
|
1656 |
+
-----BEGIN CERTIFICATE-----
|
1657 |
+
MIID5TCCAs2gAwIBAgIEOeSXnjANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UEBhMCVVMxFDASBgNV
|
1658 |
+
BAoTC1dlbGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhv
|
1659 |
+
cml0eTEvMC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN
|
1660 |
+
MDAxMDExMTY0MTI4WhcNMjEwMTE0MTY0MTI4WjCBgjELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1dl
|
1661 |
+
bGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEv
|
1662 |
+
MC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG
|
1663 |
+
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVqDM7Jvk0/82bfuUER84A4n135zHCLielTWi5MbqNQ1mX
|
1664 |
+
x3Oqfz1cQJ4F5aHiidlMuD+b+Qy0yGIZLEWukR5zcUHESxP9cMIlrCL1dQu3U+SlK93OvRw6esP3
|
1665 |
+
E48mVJwWa2uv+9iWsWCaSOAlIiR5NM4OJgALTqv9i86C1y8IcGjBqAr5dE8Hq6T54oN+J3N0Prj5
|
1666 |
+
OEL8pahbSCOz6+MlsoCultQKnMJ4msZoGK43YjdeUXWoWGPAUe5AeH6orxqg4bB4nVCMe+ez/I4j
|
1667 |
+
sNtlAHCEAQgAFG5Uhpq6zPk3EPbg3oQtnaSFN9OH4xXQwReQfhkhahKpdv0SAulPIV4XAgMBAAGj
|
1668 |
+
YTBfMA8GA1UdEwEB/wQFMAMBAf8wTAYDVR0gBEUwQzBBBgtghkgBhvt7hwcBCzAyMDAGCCsGAQUF
|
1669 |
+
BwIBFiRodHRwOi8vd3d3LndlbGxzZmFyZ28uY29tL2NlcnRwb2xpY3kwDQYJKoZIhvcNAQEFBQAD
|
1670 |
+
ggEBANIn3ZwKdyu7IvICtUpKkfnRLb7kuxpo7w6kAOnu5+/u9vnldKTC2FJYxHT7zmu1Oyl5GFrv
|
1671 |
+
m+0fazbuSCUlFLZWohDo7qd/0D+j0MNdJu4HzMPBJCGHHt8qElNvQRbn7a6U+oxy+hNH8Dx+rn0R
|
1672 |
+
OhPs7fpvcmR7nX1/Jv16+yWt6j4pf0zjAFcysLPp7VMX2YuyFA4w6OXVE8Zkr8QA1dhYJPz1j+zx
|
1673 |
+
x32l2w8n0cbyQIjmH/ZhqPRCyLk306m+LFZ4wnKbWV01QIroTmMatukgalHizqSQ33ZwmVxwQ023
|
1674 |
+
tqcZZE6St8WRPH9IFmV7Fv3L/PvZ1dZPIWU7Sn9Ho/s=
|
1675 |
+
-----END CERTIFICATE-----
|
1676 |
+
|
1677 |
+
Swisscom Root CA 1
|
1678 |
+
==================
|
1679 |
+
-----BEGIN CERTIFICATE-----
|
1680 |
+
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
|
1706 |
+
NY6E0F/6MBr1mmz0DlP5OlvRHA==
|
1707 |
+
-----END CERTIFICATE-----
|
1708 |
+
|
1709 |
+
DigiCert Assured ID Root CA
|
1710 |
+
===========================
|
1711 |
+
-----BEGIN CERTIFICATE-----
|
1712 |
+
MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG
|
1713 |
+
EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw
|
1714 |
+
IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx
|
1715 |
+
MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL
|
1716 |
+
ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew
|
1717 |
+
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO
|
1718 |
+
9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy
|
1719 |
+
UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW
|
1720 |
+
/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy
|
1721 |
+
oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf
|
1722 |
+
GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF
|
1723 |
+
66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq
|
1724 |
+
hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc
|
1725 |
+
EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn
|
1726 |
+
SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i
|
1727 |
+
8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
|
1728 |
+
+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
|
1729 |
+
-----END CERTIFICATE-----
|
1730 |
+
|
1731 |
+
DigiCert Global Root CA
|
1732 |
+
=======================
|
1733 |
+
-----BEGIN CERTIFICATE-----
|
1734 |
+
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG
|
1735 |
+
EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw
|
1736 |
+
HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw
|
1737 |
+
MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
|
1738 |
+
dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq
|
1739 |
+
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn
|
1740 |
+
TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5
|
1741 |
+
BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H
|
1742 |
+
4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y
|
1743 |
+
7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB
|
1744 |
+
o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm
|
1745 |
+
8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF
|
1746 |
+
BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr
|
1747 |
+
EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt
|
1748 |
+
tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886
|
1749 |
+
UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
|
1750 |
+
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
|
1751 |
+
-----END CERTIFICATE-----
|
1752 |
+
|
1753 |
+
DigiCert High Assurance EV Root CA
|
1754 |
+
==================================
|
1755 |
+
-----BEGIN CERTIFICATE-----
|
1756 |
+
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG
|
1757 |
+
EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw
|
1758 |
+
KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw
|
1759 |
+
MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
|
1760 |
+
MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu
|
1761 |
+
Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t
|
1762 |
+
Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS
|
1763 |
+
OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3
|
1764 |
+
MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ
|
1765 |
+
NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe
|
1766 |
+
h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB
|
1767 |
+
Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY
|
1768 |
+
JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ
|
1769 |
+
V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp
|
1770 |
+
myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK
|
1771 |
+
mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
|
1772 |
+
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K
|
1773 |
+
-----END CERTIFICATE-----
|
1774 |
+
|
1775 |
+
Certplus Class 2 Primary CA
|
1776 |
+
===========================
|
1777 |
+
-----BEGIN CERTIFICATE-----
|
1778 |
+
MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkGA1UE
|
1779 |
+
BhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkgQ0EwHhcN
|
1780 |
+
OTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2Vy
|
1781 |
+
dHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
1782 |
+
ADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR
|
1783 |
+
5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyLkcAbmXuZ
|
1784 |
+
Vg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCdEgETjdyAYveVqUSISnFO
|
1785 |
+
YFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yasH7WLO7dDWWuwJKZtkIvEcupdM5i3y95e
|
1786 |
+
e++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRME
|
1787 |
+
CDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJ
|
1788 |
+
YIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29t
|
1789 |
+
L0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvD
|
1790 |
+
P9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1R
|
1791 |
+
TtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+
|
1792 |
+
7UCmnYR0ObncHoUW2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW
|
1793 |
+
//1IMwrh3KWBkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7
|
1794 |
+
l7+ijrRU
|
1795 |
+
-----END CERTIFICATE-----
|
1796 |
+
|
1797 |
+
DST Root CA X3
|
1798 |
+
==============
|
1799 |
+
-----BEGIN CERTIFICATE-----
|
1800 |
+
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK
|
1801 |
+
ExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X
|
1802 |
+
DTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1
|
1803 |
+
cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD
|
1804 |
+
ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT
|
1805 |
+
rE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9
|
1806 |
+
UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy
|
1807 |
+
xXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d
|
1808 |
+
utolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T
|
1809 |
+
AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ
|
1810 |
+
MA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug
|
1811 |
+
dB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE
|
1812 |
+
GB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw
|
1813 |
+
RLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS
|
1814 |
+
fZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
|
1815 |
+
-----END CERTIFICATE-----
|
1816 |
+
|
1817 |
+
DST ACES CA X6
|
1818 |
+
==============
|
1819 |
+
-----BEGIN CERTIFICATE-----
|
1820 |
+
MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBbMQswCQYDVQQG
|
1821 |
+
EwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QxETAPBgNVBAsTCERTVCBBQ0VT
|
1822 |
+
MRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0wMzExMjAyMTE5NThaFw0xNzExMjAyMTE5NTha
|
1823 |
+
MFsxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UE
|
1824 |
+
CxMIRFNUIEFDRVMxFzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOC
|
1825 |
+
AQ8AMIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPuktKe1jzI
|
1826 |
+
DZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7gLFViYsx+tC3dr5BPTCa
|
1827 |
+
pCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZHfAjIgrrep4c9oW24MFbCswKBXy314pow
|
1828 |
+
GCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4aahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPy
|
1829 |
+
MjwmR/onJALJfh1biEITajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1Ud
|
1830 |
+
EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rkc3Qu
|
1831 |
+
Y29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjtodHRwOi8vd3d3LnRy
|
1832 |
+
dXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMtaW5kZXguaHRtbDAdBgNVHQ4EFgQU
|
1833 |
+
CXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZIhvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V2
|
1834 |
+
5FYrnJmQ6AgwbN99Pe7lv7UkQIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6t
|
1835 |
+
Fr8hlxCBPeP/h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq
|
1836 |
+
nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpRrscL9yuwNwXs
|
1837 |
+
vFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf29w4LTJxoeHtxMcfrHuBnQfO3
|
1838 |
+
oKfN5XozNmr6mis=
|
1839 |
+
-----END CERTIFICATE-----
|
1840 |
+
|
1841 |
+
TURKTRUST Certificate Services Provider Root 1
|
1842 |
+
==============================================
|
1843 |
+
-----BEGIN CERTIFICATE-----
|
1844 |
+
MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOcUktUUlVTVCBF
|
1845 |
+
bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGDAJUUjEP
|
1846 |
+
MA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykgMjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0
|
1847 |
+
acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMx
|
1848 |
+
MDI3MTdaFw0xNTAzMjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsg
|
1849 |
+
U2VydGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYDVQQHDAZB
|
1850 |
+
TktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBC
|
1851 |
+
aWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEuxZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOC
|
1852 |
+
AQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GX
|
1853 |
+
yGl8hMW0kWxsE2qkVa2kheiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8i
|
1854 |
+
Si9BB35JYbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5CurKZ
|
1855 |
+
8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1JuTm5Rh8i27fbMx4
|
1856 |
+
W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51b0dewQIDAQABoxAwDjAMBgNVHRME
|
1857 |
+
BTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46
|
1858 |
+
sWrv7/hg0Uw2ZkUd82YCdAR7kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxE
|
1859 |
+
q8Sn5RTOPEFhfEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy
|
1860 |
+
B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdAaLX/7KfS0zgY
|
1861 |
+
nNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKSRGQDJereW26fyfJOrN3H
|
1862 |
+
-----END CERTIFICATE-----
|
1863 |
+
|
1864 |
+
TURKTRUST Certificate Services Provider Root 2
|
1865 |
+
==============================================
|
1866 |
+
-----BEGIN CERTIFICATE-----
|
1867 |
+
MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBF
|
1868 |
+
bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP
|
1869 |
+
MA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg
|
1870 |
+
QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcN
|
1871 |
+
MDUxMTA3MTAwNzU3WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVr
|
1872 |
+
dHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEPMA0G
|
1873 |
+
A1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmls
|
1874 |
+
acWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwggEiMA0G
|
1875 |
+
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqe
|
1876 |
+
LCDe2JAOCtFp0if7qnefJ1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKI
|
1877 |
+
x+XlZEdhR3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJQv2g
|
1878 |
+
QrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGXJHpsmxcPbe9TmJEr
|
1879 |
+
5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1pzpwACPI2/z7woQ8arBT9pmAPAgMB
|
1880 |
+
AAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58SFq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8G
|
1881 |
+
A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/ntt
|
1882 |
+
Rbj2hWyfIvwqECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4
|
1883 |
+
Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFzgw2lGh1uEpJ+
|
1884 |
+
hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotHuFEJjOp9zYhys2AzsfAKRO8P
|
1885 |
+
9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LSy3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5
|
1886 |
+
UrbnBEI=
|
1887 |
+
-----END CERTIFICATE-----
|
1888 |
+
|
1889 |
+
SwissSign Platinum CA - G2
|
1890 |
+
==========================
|
1891 |
+
-----BEGIN CERTIFICATE-----
|
1892 |
+
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
|
1918 |
+
-----END CERTIFICATE-----
|
1919 |
+
|
1920 |
+
SwissSign Gold CA - G2
|
1921 |
+
======================
|
1922 |
+
-----BEGIN CERTIFICATE-----
|
1923 |
+
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
|
1949 |
+
-----END CERTIFICATE-----
|
1950 |
+
|
1951 |
+
SwissSign Silver CA - G2
|
1952 |
+
========================
|
1953 |
+
-----BEGIN CERTIFICATE-----
|
1954 |
+
MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT
|
1955 |
+
BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X
|
1956 |
+
DTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3
|
1957 |
+
aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG
|
1958 |
+
9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644
|
1959 |
+
N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm
|
1960 |
+
+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH
|
1961 |
+
6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu
|
1962 |
+
MGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h
|
1963 |
+
qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5
|
1964 |
+
FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs
|
1965 |
+
ROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc
|
1966 |
+
celM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X
|
1967 |
+
CO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
|
1968 |
+
BAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB
|
1969 |
+
tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0
|
1970 |
+
cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P
|
1971 |
+
4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F
|
1972 |
+
kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L
|
1973 |
+
3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx
|
1974 |
+
/uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa
|
1975 |
+
DGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP
|
1976 |
+
e97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu
|
1977 |
+
WxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ
|
1978 |
+
DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub
|
1979 |
+
DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u
|
1980 |
+
-----END CERTIFICATE-----
|
1981 |
+
|
1982 |
+
GeoTrust Primary Certification Authority
|
1983 |
+
========================================
|
1984 |
+
-----BEGIN CERTIFICATE-----
|
1985 |
+
MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG
|
1986 |
+
EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD
|
1987 |
+
ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx
|
1988 |
+
CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ
|
1989 |
+
cmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
1990 |
+
CgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN
|
1991 |
+
b6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9
|
1992 |
+
nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge
|
1993 |
+
RwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt
|
1994 |
+
tm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
|
1995 |
+
AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI
|
1996 |
+
hvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K
|
1997 |
+
Ts4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN
|
1998 |
+
NWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa
|
1999 |
+
Floxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG
|
2000 |
+
1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=
|
2001 |
+
-----END CERTIFICATE-----
|
2002 |
+
|
2003 |
+
thawte Primary Root CA
|
2004 |
+
======================
|
2005 |
+
-----BEGIN CERTIFICATE-----
|
2006 |
+
MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE
|
2007 |
+
BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2
|
2008 |
+
aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv
|
2009 |
+
cml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3
|
2010 |
+
MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg
|
2011 |
+
SW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv
|
2012 |
+
KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT
|
2013 |
+
FnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs
|
2014 |
+
oPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ
|
2015 |
+
1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc
|
2016 |
+
q/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K
|
2017 |
+
aAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p
|
2018 |
+
afs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD
|
2019 |
+
VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF
|
2020 |
+
AAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE
|
2021 |
+
uzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
|
2022 |
+
xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89
|
2023 |
+
jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH
|
2024 |
+
z7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA==
|
2025 |
+
-----END CERTIFICATE-----
|
2026 |
+
|
2027 |
+
VeriSign Class 3 Public Primary Certification Authority - G5
|
2028 |
+
============================================================
|
2029 |
+
-----BEGIN CERTIFICATE-----
|
2030 |
+
MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
|
2031 |
+
BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO
|
2032 |
+
ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk
|
2033 |
+
IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp
|
2034 |
+
ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB
|
2035 |
+
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln
|
2036 |
+
biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh
|
2037 |
+
dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt
|
2038 |
+
YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
|
2039 |
+
ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz
|
2040 |
+
j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD
|
2041 |
+
Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/
|
2042 |
+
Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r
|
2043 |
+
fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/
|
2044 |
+
BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv
|
2045 |
+
Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
|
2046 |
+
aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG
|
2047 |
+
SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+
|
2048 |
+
X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE
|
2049 |
+
KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC
|
2050 |
+
Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE
|
2051 |
+
ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
|
2052 |
+
-----END CERTIFICATE-----
|
2053 |
+
|
2054 |
+
SecureTrust CA
|
2055 |
+
==============
|
2056 |
+
-----BEGIN CERTIFICATE-----
|
2057 |
+
MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG
|
2058 |
+
EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy
|
2059 |
+
dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe
|
2060 |
+
BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC
|
2061 |
+
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX
|
2062 |
+
OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t
|
2063 |
+
DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH
|
2064 |
+
GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b
|
2065 |
+
01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH
|
2066 |
+
ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/
|
2067 |
+
BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj
|
2068 |
+
aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ
|
2069 |
+
KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu
|
2070 |
+
SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf
|
2071 |
+
mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ
|
2072 |
+
nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
|
2073 |
+
3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
|
2074 |
+
-----END CERTIFICATE-----
|
2075 |
+
|
2076 |
+
Secure Global CA
|
2077 |
+
================
|
2078 |
+
-----BEGIN CERTIFICATE-----
|
2079 |
+
MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG
|
2080 |
+
EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH
|
2081 |
+
bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg
|
2082 |
+
MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg
|
2083 |
+
Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx
|
2084 |
+
YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ
|
2085 |
+
bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g
|
2086 |
+
8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV
|
2087 |
+
HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi
|
2088 |
+
0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud
|
2089 |
+
EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn
|
2090 |
+
oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA
|
2091 |
+
MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+
|
2092 |
+
OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn
|
2093 |
+
CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5
|
2094 |
+
3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
|
2095 |
+
f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
|
2096 |
+
-----END CERTIFICATE-----
|
2097 |
+
|
2098 |
+
COMODO Certification Authority
|
2099 |
+
==============================
|
2100 |
+
-----BEGIN CERTIFICATE-----
|
2101 |
+
MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE
|
2102 |
+
BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG
|
2103 |
+
A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1
|
2104 |
+
dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb
|
2105 |
+
MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD
|
2106 |
+
T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
|
2107 |
+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH
|
2108 |
+
+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww
|
2109 |
+
xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV
|
2110 |
+
4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA
|
2111 |
+
1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI
|
2112 |
+
rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E
|
2113 |
+
BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k
|
2114 |
+
b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC
|
2115 |
+
AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP
|
2116 |
+
OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
|
2117 |
+
RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc
|
2118 |
+
IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN
|
2119 |
+
+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ==
|
2120 |
+
-----END CERTIFICATE-----
|
2121 |
+
|
2122 |
+
Network Solutions Certificate Authority
|
2123 |
+
=======================================
|
2124 |
+
-----BEGIN CERTIFICATE-----
|
2125 |
+
MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG
|
2126 |
+
EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr
|
2127 |
+
IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx
|
2128 |
+
MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu
|
2129 |
+
MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G
|
2130 |
+
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx
|
2131 |
+
jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT
|
2132 |
+
aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT
|
2133 |
+
crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc
|
2134 |
+
/Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB
|
2135 |
+
AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP
|
2136 |
+
BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv
|
2137 |
+
bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA
|
2138 |
+
A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q
|
2139 |
+
4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/
|
2140 |
+
GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv
|
2141 |
+
wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD
|
2142 |
+
ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey
|
2143 |
+
-----END CERTIFICATE-----
|
2144 |
+
|
2145 |
+
WellsSecure Public Root Certificate Authority
|
2146 |
+
=============================================
|
2147 |
+
-----BEGIN CERTIFICATE-----
|
2148 |
+
MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoM
|
2149 |
+
F1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYw
|
2150 |
+
NAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN
|
2151 |
+
MDcxMjEzMTcwNzU0WhcNMjIxMjE0MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dl
|
2152 |
+
bGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYD
|
2153 |
+
VQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G
|
2154 |
+
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+rWxxTkqxtnt3CxC5FlAM1
|
2155 |
+
iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjUDk/41itMpBb570OYj7OeUt9tkTmPOL13
|
2156 |
+
i0Nj67eT/DBMHAGTthP796EfvyXhdDcsHqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8
|
2157 |
+
bJVhHlfXBIEyg1J55oNjz7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiB
|
2158 |
+
K0HmOFafSZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/SlwxlAgMB
|
2159 |
+
AAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmwu
|
2160 |
+
cGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0PAQH/BAQDAgHGMB0GA1UdDgQWBBQm
|
2161 |
+
lRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0jBIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGB
|
2162 |
+
i6SBiDCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRww
|
2163 |
+
GgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg
|
2164 |
+
Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEBALkVsUSRzCPI
|
2165 |
+
K0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd/ZDJPHV3V3p9+N701NX3leZ0
|
2166 |
+
bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pBA4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSlj
|
2167 |
+
qHyita04pO2t/caaH/+Xc/77szWnk4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+es
|
2168 |
+
E2fDbbFwRnzVlhE9iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJ
|
2169 |
+
tylv2G0xffX8oRAHh84vWdw+WNs=
|
2170 |
+
-----END CERTIFICATE-----
|
2171 |
+
|
2172 |
+
COMODO ECC Certification Authority
|
2173 |
+
==================================
|
2174 |
+
-----BEGIN CERTIFICATE-----
|
2175 |
+
MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC
|
2176 |
+
R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE
|
2177 |
+
ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB
|
2178 |
+
dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix
|
2179 |
+
GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
|
2180 |
+
Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo
|
2181 |
+
b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X
|
2182 |
+
4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni
|
2183 |
+
wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E
|
2184 |
+
BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG
|
2185 |
+
FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA
|
2186 |
+
U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
|
2187 |
+
-----END CERTIFICATE-----
|
2188 |
+
|
2189 |
+
IGC/A
|
2190 |
+
=====
|
2191 |
+
-----BEGIN CERTIFICATE-----
|
2192 |
+
MIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYTAkZSMQ8wDQYD
|
2193 |
+
VQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVE
|
2194 |
+
Q1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZy
|
2195 |
+
MB4XDTAyMTIxMzE0MjkyM1oXDTIwMTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQI
|
2196 |
+
EwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NT
|
2197 |
+
STEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMIIB
|
2198 |
+
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaIs9z4iPf930Pfeo2aSVz2
|
2199 |
+
TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2xtgv2pGqaMVy/hcKshd+ebUyiHDKcMCW
|
2200 |
+
So7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4u0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYy
|
2201 |
+
HF2fYPepraX/z9E0+X1bF8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNd
|
2202 |
+
frGoRpAxVs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGdPDPQ
|
2203 |
+
tQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNVHSAEDjAMMAoGCCqB
|
2204 |
+
egF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAxNjAfBgNVHSMEGDAWgBSjBS8YYFDC
|
2205 |
+
iQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUFAAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RK
|
2206 |
+
q89toB9RlPhJy3Q2FLwV3duJL92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3Q
|
2207 |
+
MZsyK10XZZOYYLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg
|
2208 |
+
Crpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2aNjSaTFR+FwNI
|
2209 |
+
lQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R0982gaEbeC9xs/FZTEYYKKuF
|
2210 |
+
0mBWWg==
|
2211 |
+
-----END CERTIFICATE-----
|
2212 |
+
|
2213 |
+
Security Communication EV RootCA1
|
2214 |
+
=================================
|
2215 |
+
-----BEGIN CERTIFICATE-----
|
2216 |
+
MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDElMCMGA1UEChMc
|
2217 |
+
U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMhU2VjdXJpdHkgQ29tbXVuaWNh
|
2218 |
+
dGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIzMloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UE
|
2219 |
+
BhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNl
|
2220 |
+
Y3VyaXR5IENvbW11bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
2221 |
+
AQoCggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSERMqm4miO
|
2222 |
+
/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gOzXppFodEtZDkBp2uoQSX
|
2223 |
+
WHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4z
|
2224 |
+
ZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDFMxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4
|
2225 |
+
bepJz11sS6/vmsJWXMY1VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK
|
2226 |
+
9U2vP9eCOKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
|
2227 |
+
SIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HWtWS3irO4G8za+6xm
|
2228 |
+
iEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZq51ihPZRwSzJIxXYKLerJRO1RuGG
|
2229 |
+
Av8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDbEJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnW
|
2230 |
+
mHyojf6GPgcWkuF75x3sM3Z+Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEW
|
2231 |
+
T1MKZPlO9L9OVL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490
|
2232 |
+
-----END CERTIFICATE-----
|
2233 |
+
|
2234 |
+
OISTE WISeKey Global Root GA CA
|
2235 |
+
===============================
|
2236 |
+
-----BEGIN CERTIFICATE-----
|
2237 |
+
MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE
|
2238 |
+
BhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG
|
2239 |
+
A1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH
|
2240 |
+
bG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD
|
2241 |
+
VQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw
|
2242 |
+
IAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5
|
2243 |
+
IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9
|
2244 |
+
Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg
|
2245 |
+
Asj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD
|
2246 |
+
d50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ
|
2247 |
+
/yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R
|
2248 |
+
LoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw
|
2249 |
+
AwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ
|
2250 |
+
KoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm
|
2251 |
+
MMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4
|
2252 |
+
+vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa
|
2253 |
+
hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY
|
2254 |
+
okxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0=
|
2255 |
+
-----END CERTIFICATE-----
|
2256 |
+
|
2257 |
+
S-TRUST Authentication and Encryption Root CA 2005 PN
|
2258 |
+
=====================================================
|
2259 |
+
-----BEGIN CERTIFICATE-----
|
2260 |
+
MIIEezCCA2OgAwIBAgIQNxkY5lNUfBq1uMtZWts1tzANBgkqhkiG9w0BAQUFADCBrjELMAkGA1UE
|
2261 |
+
BhMCREUxIDAeBgNVBAgTF0JhZGVuLVd1ZXJ0dGVtYmVyZyAoQlcpMRIwEAYDVQQHEwlTdHV0dGdh
|
2262 |
+
cnQxKTAnBgNVBAoTIERldXRzY2hlciBTcGFya2Fzc2VuIFZlcmxhZyBHbWJIMT4wPAYDVQQDEzVT
|
2263 |
+
LVRSVVNUIEF1dGhlbnRpY2F0aW9uIGFuZCBFbmNyeXB0aW9uIFJvb3QgQ0EgMjAwNTpQTjAeFw0w
|
2264 |
+
NTA2MjIwMDAwMDBaFw0zMDA2MjEyMzU5NTlaMIGuMQswCQYDVQQGEwJERTEgMB4GA1UECBMXQmFk
|
2265 |
+
ZW4tV3VlcnR0ZW1iZXJnIChCVykxEjAQBgNVBAcTCVN0dXR0Z2FydDEpMCcGA1UEChMgRGV1dHNj
|
2266 |
+
aGVyIFNwYXJrYXNzZW4gVmVybGFnIEdtYkgxPjA8BgNVBAMTNVMtVFJVU1QgQXV0aGVudGljYXRp
|
2267 |
+
b24gYW5kIEVuY3J5cHRpb24gUm9vdCBDQSAyMDA1OlBOMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
|
2268 |
+
MIIBCgKCAQEA2bVKwdMz6tNGs9HiTNL1toPQb9UY6ZOvJ44TzbUlNlA0EmQpoVXhOmCTnijJ4/Ob
|
2269 |
+
4QSwI7+Vio5bG0F/WsPoTUzVJBY+h0jUJ67m91MduwwA7z5hca2/OnpYH5Q9XIHV1W/fuJvS9eXL
|
2270 |
+
g3KSwlOyggLrra1fFi2SU3bxibYs9cEv4KdKb6AwajLrmnQDaHgTncovmwsdvs91DSaXm8f1Xgqf
|
2271 |
+
eN+zvOyauu9VjxuapgdjKRdZYgkqeQd3peDRF2npW932kKvimAoA0SVtnteFhy+S8dF2g08LOlk3
|
2272 |
+
KC8zpxdQ1iALCvQm+Z845y2kuJuJja2tyWp9iRe79n+Ag3rm7QIDAQABo4GSMIGPMBIGA1UdEwEB
|
2273 |
+
/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMCkGA1UdEQQiMCCkHjAcMRowGAYDVQQDExFTVFJv
|
2274 |
+
bmxpbmUxLTIwNDgtNTAdBgNVHQ4EFgQUD8oeXHngovMpttKFswtKtWXsa1IwHwYDVR0jBBgwFoAU
|
2275 |
+
D8oeXHngovMpttKFswtKtWXsa1IwDQYJKoZIhvcNAQEFBQADggEBAK8B8O0ZPCjoTVy7pWMciDMD
|
2276 |
+
pwCHpB8gq9Yc4wYfl35UvbfRssnV2oDsF9eK9XvCAPbpEW+EoFolMeKJ+aQAPzFoLtU96G7m1R08
|
2277 |
+
P7K9n3frndOMusDXtk3sU5wPBG7qNWdX4wple5A64U8+wwCSersFiXOMy6ZNwPv2AtawB6MDwidA
|
2278 |
+
nwzkhYItr5pCHdDHjfhA7p0GVxzZotiAFP7hYy0yh9WUUpY6RsZxlj33mA6ykaqP2vROJAA5Veit
|
2279 |
+
F7nTNCtKqUDMFypVZUF0Qn71wK/Ik63yGFs9iQzbRzkk+OBM8h+wPQrKBU6JIRrjKpms/H+h8Q8b
|
2280 |
+
Hz2eBIPdltkdOpQ=
|
2281 |
+
-----END CERTIFICATE-----
|
2282 |
+
|
2283 |
+
Microsec e-Szigno Root CA
|
2284 |
+
=========================
|
2285 |
+
-----BEGIN CERTIFICATE-----
|
2286 |
+
MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAwcjELMAkGA1UE
|
2287 |
+
BhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNyb3NlYyBMdGQuMRQwEgYDVQQL
|
2288 |
+
EwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9zZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0
|
2289 |
+
MDYxMjI4NDRaFw0xNzA0MDYxMjI4NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVz
|
2290 |
+
dDEWMBQGA1UEChMNTWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMT
|
2291 |
+
GU1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
2292 |
+
AQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2uuO/TEdyB5s87lozWbxXG
|
2293 |
+
d36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/N
|
2294 |
+
oqdNAoI/gqyFxuEPkEeZlApxcpMqyabAvjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjc
|
2295 |
+
QR/Ji3HWVBTji1R4P770Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJ
|
2296 |
+
PqW+jqpx62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcBAQRb
|
2297 |
+
MFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3AwLQYIKwYBBQUHMAKG
|
2298 |
+
IWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAPBgNVHRMBAf8EBTADAQH/MIIBcwYD
|
2299 |
+
VR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIBAQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3
|
2300 |
+
LmUtc3ppZ25vLmh1L1NaU1ovMIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0A
|
2301 |
+
dAB2AOEAbgB5ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn
|
2302 |
+
AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABTAHoAbwBsAGcA
|
2303 |
+
4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABhACAAcwB6AGUAcgBpAG4AdAAg
|
2304 |
+
AGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABoAHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMA
|
2305 |
+
egBpAGcAbgBvAC4AaAB1AC8AUwBaAFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6
|
2306 |
+
Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NO
|
2307 |
+
PU1pY3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxPPU1pY3Jv
|
2308 |
+
c2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDtiaW5h
|
2309 |
+
cnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuBEGluZm9AZS1zemlnbm8uaHWkdzB1MSMw
|
2310 |
+
IQYDVQQDDBpNaWNyb3NlYyBlLVN6aWduw7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhT
|
2311 |
+
WjEWMBQGA1UEChMNTWljcm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhV
|
2312 |
+
MIGsBgNVHSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJIVTER
|
2313 |
+
MA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDASBgNVBAsTC2UtU3pp
|
2314 |
+
Z25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBSb290IENBghEAzLjnv04pGv2i3Gal
|
2315 |
+
HCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMT
|
2316 |
+
nGZjWS7KXHAM/IO8VbH0jgdsZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FE
|
2317 |
+
aGAHQzAxQmHl7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a
|
2318 |
+
86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfRhUZLphK3dehK
|
2319 |
+
yVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/MPMMNz7UwiiAc7EBt51alhQB
|
2320 |
+
S6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU=
|
2321 |
+
-----END CERTIFICATE-----
|
2322 |
+
|
2323 |
+
Certigna
|
2324 |
+
========
|
2325 |
+
-----BEGIN CERTIFICATE-----
|
2326 |
+
MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw
|
2327 |
+
EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3
|
2328 |
+
MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI
|
2329 |
+
Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q
|
2330 |
+
XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH
|
2331 |
+
GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p
|
2332 |
+
ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg
|
2333 |
+
DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf
|
2334 |
+
Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ
|
2335 |
+
tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ
|
2336 |
+
BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J
|
2337 |
+
SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA
|
2338 |
+
hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+
|
2339 |
+
ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu
|
2340 |
+
PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY
|
2341 |
+
1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw
|
2342 |
+
WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
|
2343 |
+
-----END CERTIFICATE-----
|
2344 |
+
|
2345 |
+
AC Ra\xC3\xADz Certic\xC3\xA1mara S.A.
|
2346 |
+
======================================
|
2347 |
+
-----BEGIN CERTIFICATE-----
|
2348 |
+
MIIGZjCCBE6gAwIBAgIPB35Sk3vgFeNX8GmMy+wMMA0GCSqGSIb3DQEBBQUAMHsxCzAJBgNVBAYT
|
2349 |
+
AkNPMUcwRQYDVQQKDD5Tb2NpZWRhZCBDYW1lcmFsIGRlIENlcnRpZmljYWNpw7NuIERpZ2l0YWwg
|
2350 |
+
LSBDZXJ0aWPDoW1hcmEgUy5BLjEjMCEGA1UEAwwaQUMgUmHDrXogQ2VydGljw6FtYXJhIFMuQS4w
|
2351 |
+
HhcNMDYxMTI3MjA0NjI5WhcNMzAwNDAyMjE0MjAyWjB7MQswCQYDVQQGEwJDTzFHMEUGA1UECgw+
|
2352 |
+
U29jaWVkYWQgQ2FtZXJhbCBkZSBDZXJ0aWZpY2FjacOzbiBEaWdpdGFsIC0gQ2VydGljw6FtYXJh
|
2353 |
+
IFMuQS4xIzAhBgNVBAMMGkFDIFJhw616IENlcnRpY8OhbWFyYSBTLkEuMIICIjANBgkqhkiG9w0B
|
2354 |
+
AQEFAAOCAg8AMIICCgKCAgEAq2uJo1PMSCMI+8PPUZYILrgIem08kBeGqentLhM0R7LQcNzJPNCN
|
2355 |
+
yu5LF6vQhbCnIwTLqKL85XXbQMpiiY9QngE9JlsYhBzLfDe3fezTf3MZsGqy2IiKLUV0qPezuMDU
|
2356 |
+
2s0iiXRNWhU5cxh0T7XrmafBHoi0wpOQY5fzp6cSsgkiBzPZkc0OnB8OIMfuuzONj8LSWKdf/WU3
|
2357 |
+
4ojC2I+GdV75LaeHM/J4Ny+LvB2GNzmxlPLYvEqcgxhaBvzz1NS6jBUJJfD5to0EfhcSM2tXSExP
|
2358 |
+
2yYe68yQ54v5aHxwD6Mq0Do43zeX4lvegGHTgNiRg0JaTASJaBE8rF9ogEHMYELODVoqDA+bMMCm
|
2359 |
+
8Ibbq0nXl21Ii/kDwFJnmxL3wvIumGVC2daa49AZMQyth9VXAnow6IYm+48jilSH5L887uvDdUhf
|
2360 |
+
HjlvgWJsxS3EF1QZtzeNnDeRyPYL1epjb4OsOMLzP96a++EjYfDIJss2yKHzMI+ko6Kh3VOz3vCa
|
2361 |
+
Mh+DkXkwwakfU5tTohVTP92dsxA7SH2JD/ztA/X7JWR1DhcZDY8AFmd5ekD8LVkH2ZD6mq093ICK
|
2362 |
+
5lw1omdMEWux+IBkAC1vImHFrEsm5VoQgpukg3s0956JkSCXjrdCx2bD0Omk1vUgjcTDlaxECp1b
|
2363 |
+
czwmPS9KvqfJpxAe+59QafMCAwEAAaOB5jCB4zAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
|
2364 |
+
AwIBBjAdBgNVHQ4EFgQU0QnQ6dfOeXRU+Tows/RtLAMDG2gwgaAGA1UdIASBmDCBlTCBkgYEVR0g
|
2365 |
+
ADCBiTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5jZXJ0aWNhbWFyYS5jb20vZHBjLzBaBggrBgEF
|
2366 |
+
BQcCAjBOGkxMaW1pdGFjaW9uZXMgZGUgZ2FyYW507WFzIGRlIGVzdGUgY2VydGlmaWNhZG8gc2Ug
|
2367 |
+
cHVlZGVuIGVuY29udHJhciBlbiBsYSBEUEMuMA0GCSqGSIb3DQEBBQUAA4ICAQBclLW4RZFNjmEf
|
2368 |
+
AygPU3zmpFmps4p6xbD/CHwso3EcIRNnoZUSQDWDg4902zNc8El2CoFS3UnUmjIz75uny3XlesuX
|
2369 |
+
EpBcunvFm9+7OSPI/5jOCk0iAUgHforA1SBClETvv3eiiWdIG0ADBaGJ7M9i4z0ldma/Jre7Ir5v
|
2370 |
+
/zlXdLp6yQGVwZVR6Kss+LGGIOk/yzVb0hfpKv6DExdA7ohiZVvVO2Dpezy4ydV/NgIlqmjCMRW3
|
2371 |
+
MGXrfx1IebHPOeJCgBbT9ZMj/EyXyVo3bHwi2ErN0o42gzmRkBDI8ck1fj+404HGIGQatlDCIaR4
|
2372 |
+
3NAvO2STdPCWkPHv+wlaNECW8DYSwaN0jJN+Qd53i+yG2dIPPy3RzECiiWZIHiCznCNZc6lEc7wk
|
2373 |
+
eZBWN7PGKX6jD/EpOe9+XCgycDWs2rjIdWb8m0w5R44bb5tNAlQiM+9hup4phO9OSzNHdpdqy35f
|
2374 |
+
/RWmnkJDW2ZaiogN9xa5P1FlK2Zqi9E4UqLWRhH6/JocdJ6PlwsCT2TG9WjTSy3/pDceiz+/RL5h
|
2375 |
+
RqGEPQgnTIEgd4kI6mdAXmwIUV80WoyWaM3X94nCHNMyAK9Sy9NgWyo6R35rMDOhYil/SrnhLecU
|
2376 |
+
Iw4OGEfhefwVVdCx/CVxY3UzHCMrr1zZ7Ud3YA47Dx7SwNxkBYn8eNZcLCZDqQ==
|
2377 |
+
-----END CERTIFICATE-----
|
2378 |
+
|
2379 |
+
TC TrustCenter Class 2 CA II
|
2380 |
+
============================
|
2381 |
+
-----BEGIN CERTIFICATE-----
|
2382 |
+
MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC
|
2383 |
+
REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy
|
2384 |
+
IENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYw
|
2385 |
+
MTEyMTQzODQzWhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1
|
2386 |
+
c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UE
|
2387 |
+
AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
2388 |
+
AQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jftMjWQ+nEdVl//OEd+DFw
|
2389 |
+
IxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKguNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2
|
2390 |
+
xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2JXjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQ
|
2391 |
+
Xa7pIXSSTYtZgo+U4+lK8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7u
|
2392 |
+
SNQZu+995OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1UdEwEB
|
2393 |
+
/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3kUrL84J6E1wIqzCB
|
2394 |
+
7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90
|
2395 |
+
Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU
|
2396 |
+
cnVzdENlbnRlciUyMENsYXNzJTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i
|
2397 |
+
SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
|
2398 |
+
TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iSGNn3Bzn1LL4G
|
2399 |
+
dXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprtZjluS5TmVfwLG4t3wVMTZonZ
|
2400 |
+
KNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8au0WOB9/WIFaGusyiC2y8zl3gK9etmF1Kdsj
|
2401 |
+
TYjKUCjLhdLTEKJZbtOTVAB6okaVhgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kP
|
2402 |
+
JOzHdiEoZa5X6AeIdUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfk
|
2403 |
+
vQ==
|
2404 |
+
-----END CERTIFICATE-----
|
2405 |
+
|
2406 |
+
TC TrustCenter Class 3 CA II
|
2407 |
+
============================
|
2408 |
+
-----BEGIN CERTIFICATE-----
|
2409 |
+
MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC
|
2410 |
+
REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy
|
2411 |
+
IENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYw
|
2412 |
+
MTEyMTQ0MTU3WhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1
|
2413 |
+
c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UE
|
2414 |
+
AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
2415 |
+
AQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJWHt4bNwcwIi9v8Qbxq63W
|
2416 |
+
yKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+QVl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo
|
2417 |
+
6SI7dYnWRBpl8huXJh0obazovVkdKyT21oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZ
|
2418 |
+
uV3bOx4a+9P/FRQI2AlqukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk
|
2419 |
+
2ZyqBwi1Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1UdEwEB
|
2420 |
+
/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NXXAek0CSnwPIA1DCB
|
2421 |
+
7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90
|
2422 |
+
Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU
|
2423 |
+
cnVzdENlbnRlciUyMENsYXNzJTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i
|
2424 |
+
SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
|
2425 |
+
TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlNirTzwppVMXzE
|
2426 |
+
O2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8TtXqluJucsG7Kv5sbviRmEb8
|
2427 |
+
yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9
|
2428 |
+
IJqDnxrcOfHFcqMRA/07QlIp2+gB95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal
|
2429 |
+
092Y+tTmBvTwtiBjS+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc
|
2430 |
+
5A==
|
2431 |
+
-----END CERTIFICATE-----
|
2432 |
+
|
2433 |
+
TC TrustCenter Universal CA I
|
2434 |
+
=============================
|
2435 |
+
-----BEGIN CERTIFICATE-----
|
2436 |
+
MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTELMAkGA1UEBhMC
|
2437 |
+
REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVy
|
2438 |
+
IFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcN
|
2439 |
+
MDYwMzIyMTU1NDI4WhcNMjUxMjMxMjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMg
|
2440 |
+
VHJ1c3RDZW50ZXIgR21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYw
|
2441 |
+
JAYDVQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcNAQEBBQAD
|
2442 |
+
ggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSRJJZ4Hgmgm5qVSkr1YnwC
|
2443 |
+
qMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3TfCZdzHd55yx4Oagmcw6iXSVphU9VDprv
|
2444 |
+
xrlE4Vc93x9UIuVvZaozhDrzznq+VZeujRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtw
|
2445 |
+
ag+1m7Z3W0hZneTvWq3zwZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9O
|
2446 |
+
gdwZu5GQfezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYDVR0j
|
2447 |
+
BBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
|
2448 |
+
AYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0GCSqGSIb3DQEBBQUAA4IBAQAo0uCG
|
2449 |
+
1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X17caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/Cy
|
2450 |
+
vwbZ71q+s2IhtNerNXxTPqYn8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3
|
2451 |
+
ghUJGooWMNjsydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT
|
2452 |
+
ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/2TYcuiUaUj0a
|
2453 |
+
7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY
|
2454 |
+
-----END CERTIFICATE-----
|
2455 |
+
|
2456 |
+
Deutsche Telekom Root CA 2
|
2457 |
+
==========================
|
2458 |
+
-----BEGIN CERTIFICATE-----
|
2459 |
+
MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMT
|
2460 |
+
RGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEG
|
2461 |
+
A1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5
|
2462 |
+
MjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G
|
2463 |
+
A1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBS
|
2464 |
+
b290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEUha88EOQ5
|
2465 |
+
bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhCQN/Po7qCWWqSG6wcmtoI
|
2466 |
+
KyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1MjwrrFDa1sPeg5TKqAyZMg4ISFZbavva4VhY
|
2467 |
+
AUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aK
|
2468 |
+
Se5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTV
|
2469 |
+
jlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNV
|
2470 |
+
HRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynr
|
2471 |
+
E/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSy
|
2472 |
+
zhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8
|
2473 |
+
rZ7/gFnkm0W09juwzTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4G
|
2474 |
+
dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU
|
2475 |
+
Cm26OWMohpLzGITY+9HPBVZkVw==
|
2476 |
+
-----END CERTIFICATE-----
|
2477 |
+
|
2478 |
+
ComSign CA
|
2479 |
+
==========
|
2480 |
+
-----BEGIN CERTIFICATE-----
|
2481 |
+
MIIDkzCCAnugAwIBAgIQFBOWgxRVjOp7Y+X8NId3RDANBgkqhkiG9w0BAQUFADA0MRMwEQYDVQQD
|
2482 |
+
EwpDb21TaWduIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTMy
|
2483 |
+
MThaFw0yOTAzMTkxNTAyMThaMDQxEzARBgNVBAMTCkNvbVNpZ24gQ0ExEDAOBgNVBAoTB0NvbVNp
|
2484 |
+
Z24xCzAJBgNVBAYTAklMMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8ORUaSvTx49q
|
2485 |
+
ROR+WCf4C9DklBKK8Rs4OC8fMZwG1Cyn3gsqrhqg455qv588x26i+YtkbDqthVVRVKU4VbirgwTy
|
2486 |
+
P2Q298CNQ0NqZtH3FyrV7zb6MBBC11PN+fozc0yz6YQgitZBJzXkOPqUm7h65HkfM/sb2CEJKHxN
|
2487 |
+
GGleZIp6GZPKfuzzcuc3B1hZKKxC+cX/zT/npfo4sdAMx9lSGlPWgcxCejVb7Us6eva1jsz/D3zk
|
2488 |
+
YDaHL63woSV9/9JLEYhwVKZBqGdTUkJe5DSe5L6j7KpiXd3DTKaCQeQzC6zJMw9kglcq/QytNuEM
|
2489 |
+
rkvF7zuZ2SOzW120V+x0cAwqTwIDAQABo4GgMIGdMAwGA1UdEwQFMAMBAf8wPQYDVR0fBDYwNDAy
|
2490 |
+
oDCgLoYsaHR0cDovL2ZlZGlyLmNvbXNpZ24uY28uaWwvY3JsL0NvbVNpZ25DQS5jcmwwDgYDVR0P
|
2491 |
+
AQH/BAQDAgGGMB8GA1UdIwQYMBaAFEsBmz5WGmU2dst7l6qSBe4y5ygxMB0GA1UdDgQWBBRLAZs+
|
2492 |
+
VhplNnbLe5eqkgXuMucoMTANBgkqhkiG9w0BAQUFAAOCAQEA0Nmlfv4pYEWdfoPPbrxHbvUanlR2
|
2493 |
+
QnG0PFg/LUAlQvaBnPGJEMgOqnhPOAlXsDzACPw1jvFIUY0McXS6hMTXcpuEfDhOZAYnKuGntewI
|
2494 |
+
mbQKDdSFc8gS4TXt8QUxHXOZDOuWyt3T5oWq8Ir7dcHyCTxlZWTzTNity4hp8+SDtwy9F1qWF8pb
|
2495 |
+
/627HOkthIDYIb6FUtnUdLlphbpN7Sgy6/lhSuTENh4Z3G+EER+V9YMoGKgzkkMn3V0TBEVPh9VG
|
2496 |
+
zT2ouvDzuFYkRes3x+F2T3I5GN9+dHLHcy056mDmrRGiVod7w2ia/viMcKjfZTL0pECMocJEAw6U
|
2497 |
+
AGegcQCCSA==
|
2498 |
+
-----END CERTIFICATE-----
|
2499 |
+
|
2500 |
+
ComSign Secured CA
|
2501 |
+
==================
|
2502 |
+
-----BEGIN CERTIFICATE-----
|
2503 |
+
MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAwPDEbMBkGA1UE
|
2504 |
+
AxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQGEwJJTDAeFw0w
|
2505 |
+
NDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwxGzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBD
|
2506 |
+
QTEQMA4GA1UEChMHQ29tU2lnbjELMAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
|
2507 |
+
ggEKAoIBAQDGtWhfHZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs
|
2508 |
+
49ohgHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sWv+bznkqH
|
2509 |
+
7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ueMv5WJDmyVIRD9YTC2LxB
|
2510 |
+
kMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d1
|
2511 |
+
9guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUw
|
2512 |
+
AwEB/zBEBgNVHR8EPTA7MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29t
|
2513 |
+
U2lnblNlY3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58ADsA
|
2514 |
+
j8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkqhkiG9w0BAQUFAAOC
|
2515 |
+
AQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7piL1DRYHjZiM/EoZNGeQFsOY3wo3a
|
2516 |
+
BijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtCdsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtp
|
2517 |
+
FhpFfTMDZflScZAmlaxMDPWLkz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP
|
2518 |
+
51qJThRv4zdLhfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz
|
2519 |
+
OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw==
|
2520 |
+
-----END CERTIFICATE-----
|
2521 |
+
|
2522 |
+
Cybertrust Global Root
|
2523 |
+
======================
|
2524 |
+
-----BEGIN CERTIFICATE-----
|
2525 |
+
MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li
|
2526 |
+
ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4
|
2527 |
+
MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD
|
2528 |
+
ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
|
2529 |
+
+Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW
|
2530 |
+
0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL
|
2531 |
+
AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin
|
2532 |
+
89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT
|
2533 |
+
8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP
|
2534 |
+
BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2
|
2535 |
+
MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G
|
2536 |
+
A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO
|
2537 |
+
lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi
|
2538 |
+
5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2
|
2539 |
+
hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T
|
2540 |
+
X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW
|
2541 |
+
WL1WMRJOEcgh4LMRkWXbtKaIOM5V
|
2542 |
+
-----END CERTIFICATE-----
|
2543 |
+
|
2544 |
+
ePKI Root Certification Authority
|
2545 |
+
=================================
|
2546 |
+
-----BEGIN CERTIFICATE-----
|
2547 |
+
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
|
2573 |
+
-----END CERTIFICATE-----
|
2574 |
+
|
2575 |
+
T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3
|
2576 |
+
=============================================================================================================================
|
2577 |
+
-----BEGIN CERTIFICATE-----
|
2578 |
+
MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRSMRgwFgYDVQQH
|
2579 |
+
DA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJpbGltc2VsIHZlIFRla25vbG9q
|
2580 |
+
aWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSwVEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ry
|
2581 |
+
b25payB2ZSBLcmlwdG9sb2ppIEFyYcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNV
|
2582 |
+
BAsMGkthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUg
|
2583 |
+
S8O2ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAeFw0wNzA4
|
2584 |
+
MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIxGDAWBgNVBAcMD0dlYnpl
|
2585 |
+
IC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmlsaW1zZWwgdmUgVGVrbm9sb2ppayBBcmHF
|
2586 |
+
n3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBUQUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZl
|
2587 |
+
IEtyaXB0b2xvamkgQXJhxZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2Ft
|
2588 |
+
dSBTZXJ0aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7ZrIFNl
|
2589 |
+
cnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIBIjANBgkqhkiG9w0B
|
2590 |
+
AQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4hgb46ezzb8R1Sf1n68yJMlaCQvEhO
|
2591 |
+
Eav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yKO7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1
|
2592 |
+
xnnRFDDtG1hba+818qEhTsXOfJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR
|
2593 |
+
6Oqeyjh1jmKwlZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL
|
2594 |
+
hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQIDAQABo0IwQDAd
|
2595 |
+
BgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
|
2596 |
+
MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmPNOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4
|
2597 |
+
N5EY3ATIZJkrGG2AA1nJrvhY0D7twyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLT
|
2598 |
+
y9LQQfMmNkqblWwM7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYh
|
2599 |
+
LBOhgLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5noN+J1q2M
|
2600 |
+
dqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUsyZyQ2uypQjyttgI=
|
2601 |
+
-----END CERTIFICATE-----
|
2602 |
+
|
2603 |
+
Buypass Class 2 CA 1
|
2604 |
+
====================
|
2605 |
+
-----BEGIN CERTIFICATE-----
|
2606 |
+
MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU
|
2607 |
+
QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMiBDQSAxMB4XDTA2
|
2608 |
+
MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh
|
2609 |
+
c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZI
|
2610 |
+
hvcNAQEBBQADggEPADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7M
|
2611 |
+
cXA0ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLXl18xoS83
|
2612 |
+
0r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVBHfCuuCkslFJgNJQ72uA4
|
2613 |
+
0Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/R
|
2614 |
+
uFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNC
|
2615 |
+
MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0P
|
2616 |
+
AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLPgcIV
|
2617 |
+
1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+DKhQ7SLHrQVMdvvt
|
2618 |
+
7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKuBctN518fV4bVIJwo+28TOPX2EZL2
|
2619 |
+
fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHsh7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5w
|
2620 |
+
wDX3OaJdZtB7WZ+oRxKaJyOkLY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho
|
2621 |
+
-----END CERTIFICATE-----
|
2622 |
+
|
2623 |
+
Buypass Class 3 CA 1
|
2624 |
+
====================
|
2625 |
+
-----BEGIN CERTIFICATE-----
|
2626 |
+
MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU
|
2627 |
+
QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMyBDQSAxMB4XDTA1
|
2628 |
+
MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh
|
2629 |
+
c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZI
|
2630 |
+
hvcNAQEBBQADggEPADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKx
|
2631 |
+
ifZgisRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//zNIqeKNc0
|
2632 |
+
n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI+MkcVyzwPX6UvCWThOia
|
2633 |
+
AJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2RhzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c
|
2634 |
+
1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNC
|
2635 |
+
MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0P
|
2636 |
+
AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFPBdy7
|
2637 |
+
pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27sEzNxZy5p+qksP2bA
|
2638 |
+
EllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2mSlf56oBzKwzqBwKu5HEA6BvtjT5
|
2639 |
+
htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yCe/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQj
|
2640 |
+
el/wroQk5PMr+4okoyeYZdowdXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915
|
2641 |
+
-----END CERTIFICATE-----
|
2642 |
+
|
2643 |
+
EBG Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1
|
2644 |
+
==========================================================================
|
2645 |
+
-----BEGIN CERTIFICATE-----
|
2646 |
+
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
|
2673 |
+
-----END CERTIFICATE-----
|
2674 |
+
|
2675 |
+
certSIGN ROOT CA
|
2676 |
+
================
|
2677 |
+
-----BEGIN CERTIFICATE-----
|
2678 |
+
MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD
|
2679 |
+
VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa
|
2680 |
+
Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE
|
2681 |
+
CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I
|
2682 |
+
JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH
|
2683 |
+
rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2
|
2684 |
+
ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD
|
2685 |
+
0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943
|
2686 |
+
AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B
|
2687 |
+
Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB
|
2688 |
+
AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8
|
2689 |
+
SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0
|
2690 |
+
x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt
|
2691 |
+
vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz
|
2692 |
+
TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD
|
2693 |
+
-----END CERTIFICATE-----
|
2694 |
+
|
2695 |
+
CNNIC ROOT
|
2696 |
+
==========
|
2697 |
+
-----BEGIN CERTIFICATE-----
|
2698 |
+
MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJDTjEOMAwGA1UE
|
2699 |
+
ChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2MDcwOTE0WhcNMjcwNDE2MDcw
|
2700 |
+
OTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1Qw
|
2701 |
+
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzD
|
2702 |
+
o+/hn7E7SIX1mlwhIhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tiz
|
2703 |
+
VHa6dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZOV/kbZKKT
|
2704 |
+
VrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrCGHn2emU1z5DrvTOTn1Or
|
2705 |
+
czvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gNv7Sg2Ca+I19zN38m5pIEo3/PIKe38zrK
|
2706 |
+
y5nLAgMBAAGjczBxMBEGCWCGSAGG+EIBAQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscC
|
2707 |
+
wQ7vptU7ETAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991S
|
2708 |
+
lgrHAsEO76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnKOOK5
|
2709 |
+
Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvHugDnuL8BV8F3RTIM
|
2710 |
+
O/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7HgviyJA/qIYM/PmLXoXLT1tLYhFHxUV8
|
2711 |
+
BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fLbuXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2
|
2712 |
+
G8kS1sHNzYDzAgE8yGnLRUhj2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5m
|
2713 |
+
mxE=
|
2714 |
+
-----END CERTIFICATE-----
|
2715 |
+
|
2716 |
+
ApplicationCA - Japanese Government
|
2717 |
+
===================================
|
2718 |
+
-----BEGIN CERTIFICATE-----
|
2719 |
+
MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEcMBoGA1UEChMT
|
2720 |
+
SmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRpb25DQTAeFw0wNzEyMTIxNTAw
|
2721 |
+
MDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYTAkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zl
|
2722 |
+
cm5tZW50MRYwFAYDVQQLEw1BcHBsaWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
2723 |
+
CgKCAQEAp23gdE6Hj6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4
|
2724 |
+
fl+Kf5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55IrmTwcrN
|
2725 |
+
wVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cwFO5cjFW6WY2H/CPek9AE
|
2726 |
+
jP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDihtQWEjdnjDuGWk81quzMKq2edY3rZ+nYVu
|
2727 |
+
nyoKb58DKTCXKB28t89UKU5RMfkntigm/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRU
|
2728 |
+
WssmP3HMlEYNllPqa0jQk/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNV
|
2729 |
+
BAYTAkpQMRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOCseOD
|
2730 |
+
vOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADlqRHZ3ODrs
|
2731 |
+
o2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJhyzjVOGjprIIC8CFqMjSnHH2HZ9g
|
2732 |
+
/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYD
|
2733 |
+
io+nEhEMy/0/ecGc/WLuo89UDNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmW
|
2734 |
+
dupwX3kSa+SjB1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL
|
2735 |
+
rosot4LKGAfmt1t06SAZf7IbiVQ=
|
2736 |
+
-----END CERTIFICATE-----
|
2737 |
+
|
2738 |
+
GeoTrust Primary Certification Authority - G3
|
2739 |
+
=============================================
|
2740 |
+
-----BEGIN CERTIFICATE-----
|
2741 |
+
MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE
|
2742 |
+
BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0
|
2743 |
+
IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy
|
2744 |
+
eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz
|
2745 |
+
NTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo
|
2746 |
+
YykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT
|
2747 |
+
LUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI
|
2748 |
+
hvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j
|
2749 |
+
K/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE
|
2750 |
+
c5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C
|
2751 |
+
IShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu
|
2752 |
+
dlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC
|
2753 |
+
MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr
|
2754 |
+
2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9
|
2755 |
+
cr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE
|
2756 |
+
Ap7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD
|
2757 |
+
AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s
|
2758 |
+
t/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt
|
2759 |
+
-----END CERTIFICATE-----
|
2760 |
+
|
2761 |
+
thawte Primary Root CA - G2
|
2762 |
+
===========================
|
2763 |
+
-----BEGIN CERTIFICATE-----
|
2764 |
+
MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC
|
2765 |
+
VVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu
|
2766 |
+
IC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg
|
2767 |
+
Q0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV
|
2768 |
+
MBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG
|
2769 |
+
b3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt
|
2770 |
+
IEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS
|
2771 |
+
LSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5
|
2772 |
+
8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU
|
2773 |
+
mtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN
|
2774 |
+
G4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K
|
2775 |
+
rr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==
|
2776 |
+
-----END CERTIFICATE-----
|
2777 |
+
|
2778 |
+
thawte Primary Root CA - G3
|
2779 |
+
===========================
|
2780 |
+
-----BEGIN CERTIFICATE-----
|
2781 |
+
MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE
|
2782 |
+
BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2
|
2783 |
+
aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv
|
2784 |
+
cml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w
|
2785 |
+
ODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh
|
2786 |
+
d3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD
|
2787 |
+
VQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG
|
2788 |
+
A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
|
2789 |
+
MIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At
|
2790 |
+
P0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC
|
2791 |
+
+BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY
|
2792 |
+
7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW
|
2793 |
+
vGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E
|
2794 |
+
BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ
|
2795 |
+
KoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK
|
2796 |
+
A3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu
|
2797 |
+
t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC
|
2798 |
+
8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm
|
2799 |
+
er/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A=
|
2800 |
+
-----END CERTIFICATE-----
|
2801 |
+
|
2802 |
+
GeoTrust Primary Certification Authority - G2
|
2803 |
+
=============================================
|
2804 |
+
-----BEGIN CERTIFICATE-----
|
2805 |
+
MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC
|
2806 |
+
VVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu
|
2807 |
+
Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD
|
2808 |
+
ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1
|
2809 |
+
OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg
|
2810 |
+
MjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl
|
2811 |
+
b1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG
|
2812 |
+
BSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc
|
2813 |
+
KiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD
|
2814 |
+
VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+
|
2815 |
+
EVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m
|
2816 |
+
ndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2
|
2817 |
+
npaqBA+K
|
2818 |
+
-----END CERTIFICATE-----
|
2819 |
+
|
2820 |
+
VeriSign Universal Root Certification Authority
|
2821 |
+
===============================================
|
2822 |
+
-----BEGIN CERTIFICATE-----
|
2823 |
+
MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE
|
2824 |
+
BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO
|
2825 |
+
ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk
|
2826 |
+
IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u
|
2827 |
+
IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV
|
2828 |
+
UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
|
2829 |
+
cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
|
2830 |
+
IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0
|
2831 |
+
aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj
|
2832 |
+
1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP
|
2833 |
+
MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72
|
2834 |
+
9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I
|
2835 |
+
AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR
|
2836 |
+
tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G
|
2837 |
+
CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O
|
2838 |
+
a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud
|
2839 |
+
DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3
|
2840 |
+
Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx
|
2841 |
+
Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx
|
2842 |
+
P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P
|
2843 |
+
wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4
|
2844 |
+
mJO37M2CYfE45k+XmCpajQ==
|
2845 |
+
-----END CERTIFICATE-----
|
2846 |
+
|
2847 |
+
VeriSign Class 3 Public Primary Certification Authority - G4
|
2848 |
+
============================================================
|
2849 |
+
-----BEGIN CERTIFICATE-----
|
2850 |
+
MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC
|
2851 |
+
VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3
|
2852 |
+
b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz
|
2853 |
+
ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj
|
2854 |
+
YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL
|
2855 |
+
MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU
|
2856 |
+
cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo
|
2857 |
+
b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5
|
2858 |
+
IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8
|
2859 |
+
Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz
|
2860 |
+
rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB
|
2861 |
+
/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw
|
2862 |
+
HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u
|
2863 |
+
Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD
|
2864 |
+
A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx
|
2865 |
+
AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==
|
2866 |
+
-----END CERTIFICATE-----
|
2867 |
+
|
2868 |
+
NetLock Arany (Class Gold) Főtanúsítvány
|
2869 |
+
============================================
|
2870 |
+
-----BEGIN CERTIFICATE-----
|
2871 |
+
MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G
|
2872 |
+
A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610
|
2873 |
+
dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB
|
2874 |
+
cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx
|
2875 |
+
MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO
|
2876 |
+
ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv
|
2877 |
+
biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6
|
2878 |
+
c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu
|
2879 |
+
0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw
|
2880 |
+
/HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk
|
2881 |
+
H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw
|
2882 |
+
fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1
|
2883 |
+
neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB
|
2884 |
+
BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW
|
2885 |
+
qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta
|
2886 |
+
YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC
|
2887 |
+
bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna
|
2888 |
+
NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu
|
2889 |
+
dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
|
2890 |
+
-----END CERTIFICATE-----
|
2891 |
+
|
2892 |
+
Staat der Nederlanden Root CA - G2
|
2893 |
+
==================================
|
2894 |
+
-----BEGIN CERTIFICATE-----
|
2895 |
+
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
|
2921 |
+
66+KAQ==
|
2922 |
+
-----END CERTIFICATE-----
|
2923 |
+
|
2924 |
+
CA Disig
|
2925 |
+
========
|
2926 |
+
-----BEGIN CERTIFICATE-----
|
2927 |
+
MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMK
|
2928 |
+
QnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwHhcNMDYw
|
2929 |
+
MzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlz
|
2930 |
+
bGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3
|
2931 |
+
DQEBAQUAA4IBDwAwggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgm
|
2932 |
+
GErENx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnXmjxUizkD
|
2933 |
+
Pw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYDXcDtab86wYqg6I7ZuUUo
|
2934 |
+
hwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhWS8+2rT+MitcE5eN4TPWGqvWP+j1scaMt
|
2935 |
+
ymfraHtuM6kMgiioTGohQBUgDCZbg8KpFhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8w
|
2936 |
+
gfwwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0P
|
2937 |
+
AQH/BAQDAgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cuZGlz
|
2938 |
+
aWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5zay9jYS9jcmwvY2Ff
|
2939 |
+
ZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2svY2EvY3JsL2NhX2Rpc2lnLmNybDAa
|
2940 |
+
BgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEwDQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59t
|
2941 |
+
WDYcPQuBDRIrRhCA/ec8J9B6yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3
|
2942 |
+
mkkp7M5+cTxqEEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/
|
2943 |
+
CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeBEicTXxChds6K
|
2944 |
+
ezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFNPGO+I++MzVpQuGhU+QqZMxEA
|
2945 |
+
4Z7CRneC9VkGjCFMhwnN5ag=
|
2946 |
+
-----END CERTIFICATE-----
|
2947 |
+
|
2948 |
+
Juur-SK
|
2949 |
+
=======
|
2950 |
+
-----BEGIN CERTIFICATE-----
|
2951 |
+
MIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcNAQkBFglwa2lA
|
2952 |
+
c2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMRAw
|
2953 |
+
DgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMwMVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqG
|
2954 |
+
SIb3DQEJARYJcGtpQHNrLmVlMQswCQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVy
|
2955 |
+
aW1pc2tlc2t1czEQMA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
|
2956 |
+
ggEBAIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOBSvZiF3tf
|
2957 |
+
TQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkzABpTpyHhOEvWgxutr2TC
|
2958 |
+
+Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvHLCu3GFH+4Hv2qEivbDtPL+/40UceJlfw
|
2959 |
+
UR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMPPbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDa
|
2960 |
+
Tpxt4brNj3pssAki14sL2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQF
|
2961 |
+
MAMBAf8wggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwICMIHD
|
2962 |
+
HoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDkAGwAagBhAHMAdABh
|
2963 |
+
AHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0AHMAZQBlAHIAaQBtAGkAcwBrAGUA
|
2964 |
+
cwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABzAGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABr
|
2965 |
+
AGkAbgBuAGkAdABhAG0AaQBzAGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nw
|
2966 |
+
cy8wKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE
|
2967 |
+
FASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcYP2/v6X2+MA4G
|
2968 |
+
A1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOiCfP+JmeaUOTDBS8rNXiRTHyo
|
2969 |
+
ERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+gkcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyL
|
2970 |
+
abVAyJRld/JXIWY7zoVAtjNjGr95HvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678
|
2971 |
+
IIbsSt4beDI3poHSna9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkh
|
2972 |
+
Mp6qqIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0ZTbvGRNs2
|
2973 |
+
yyqcjg==
|
2974 |
+
-----END CERTIFICATE-----
|
2975 |
+
|
2976 |
+
Hongkong Post Root CA 1
|
2977 |
+
=======================
|
2978 |
+
-----BEGIN CERTIFICATE-----
|
2979 |
+
MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT
|
2980 |
+
DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx
|
2981 |
+
NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n
|
2982 |
+
IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF
|
2983 |
+
AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1
|
2984 |
+
ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr
|
2985 |
+
auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh
|
2986 |
+
qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY
|
2987 |
+
V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV
|
2988 |
+
HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i
|
2989 |
+
h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio
|
2990 |
+
l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei
|
2991 |
+
IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps
|
2992 |
+
T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT
|
2993 |
+
c4afU9hDDl3WY4JxHYB0yvbiAmvZWg==
|
2994 |
+
-----END CERTIFICATE-----
|
2995 |
+
|
2996 |
+
SecureSign RootCA11
|
2997 |
+
===================
|
2998 |
+
-----BEGIN CERTIFICATE-----
|
2999 |
+
MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi
|
3000 |
+
SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS
|
3001 |
+
b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw
|
3002 |
+
KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1
|
3003 |
+
cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL
|
3004 |
+
TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO
|
3005 |
+
wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq
|
3006 |
+
g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP
|
3007 |
+
O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA
|
3008 |
+
bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX
|
3009 |
+
t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh
|
3010 |
+
OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r
|
3011 |
+
bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ
|
3012 |
+
Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01
|
3013 |
+
y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061
|
3014 |
+
lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I=
|
3015 |
+
-----END CERTIFICATE-----
|
3016 |
+
|
3017 |
+
ACEDICOM Root
|
3018 |
+
=============
|
3019 |
+
-----BEGIN CERTIFICATE-----
|
3020 |
+
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
|
3046 |
+
-----END CERTIFICATE-----
|
3047 |
+
|
3048 |
+
Verisign Class 1 Public Primary Certification Authority
|
3049 |
+
=======================================================
|
3050 |
+
-----BEGIN CERTIFICATE-----
|
3051 |
+
MIICPDCCAaUCED9pHoGc8JpK83P/uUii5N0wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx
|
3052 |
+
FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAxIFB1YmxpYyBQcmltYXJ5
|
3053 |
+
IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVow
|
3054 |
+
XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAx
|
3055 |
+
IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
|
3056 |
+
A4GNADCBiQKBgQDlGb9to1ZhLZlIcfZn3rmN67eehoAKkQ76OCWvRoiC5XOooJskXQ0fzGVuDLDQ
|
3057 |
+
VoQYh5oGmxChc9+0WDlrbsH2FdWoqD+qEgaNMax/sDTXjzRniAnNFBHiTkVWaR94AoDa3EeRKbs2
|
3058 |
+
yWNcxeDXLYd7obcysHswuiovMaruo2fa2wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFgVKTk8d6Pa
|
3059 |
+
XCUDfGD67gmZPCcQcMgMCeazh88K4hiWNWLMv5sneYlfycQJ9M61Hd8qveXbhpxoJeUwfLaJFf5n
|
3060 |
+
0a3hUKw8fGJLj7qE1xIVGx/KXQ/BUpQqEZnae88MNhPVNdwQGVnqlMEAv3WP2fr9dgTbYruQagPZ
|
3061 |
+
RjXZ+Hxb
|
3062 |
+
-----END CERTIFICATE-----
|
3063 |
+
|
3064 |
+
Verisign Class 3 Public Primary Certification Authority
|
3065 |
+
=======================================================
|
3066 |
+
-----BEGIN CERTIFICATE-----
|
3067 |
+
MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx
|
3068 |
+
FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5
|
3069 |
+
IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVow
|
3070 |
+
XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz
|
3071 |
+
IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
|
3072 |
+
A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94
|
3073 |
+
f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol
|
3074 |
+
hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABByUqkFFBky
|
3075 |
+
CEHwxWsKzH4PIRnN5GfcX6kb5sroc50i2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWX
|
3076 |
+
bj9T/UWZYB2oK0z5XqcJ2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/
|
3077 |
+
D/xwzoiQ
|
3078 |
+
-----END CERTIFICATE-----
|
3079 |
+
|
3080 |
+
Microsec e-Szigno Root CA 2009
|
3081 |
+
==============================
|
3082 |
+
-----BEGIN CERTIFICATE-----
|
3083 |
+
MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER
|
3084 |
+
MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv
|
3085 |
+
c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o
|
3086 |
+
dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE
|
3087 |
+
BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt
|
3088 |
+
U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw
|
3089 |
+
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA
|
3090 |
+
fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG
|
3091 |
+
0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA
|
3092 |
+
pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm
|
3093 |
+
1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC
|
3094 |
+
AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf
|
3095 |
+
QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE
|
3096 |
+
FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o
|
3097 |
+
lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX
|
3098 |
+
I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775
|
3099 |
+
tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02
|
3100 |
+
yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi
|
3101 |
+
LXpUq3DDfSJlgnCW
|
3102 |
+
-----END CERTIFICATE-----
|
3103 |
+
|
3104 |
+
E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi
|
3105 |
+
===================================================
|
3106 |
+
-----BEGIN CERTIFICATE-----
|
3107 |
+
MIIDtjCCAp6gAwIBAgIQRJmNPMADJ72cdpW56tustTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG
|
3108 |
+
EwJUUjEoMCYGA1UEChMfRWxla3Ryb25payBCaWxnaSBHdXZlbmxpZ2kgQS5TLjE8MDoGA1UEAxMz
|
3109 |
+
ZS1HdXZlbiBLb2sgRWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhZ2xheWljaXNpMB4XDTA3
|
3110 |
+
MDEwNDExMzI0OFoXDTE3MDEwNDExMzI0OFowdTELMAkGA1UEBhMCVFIxKDAmBgNVBAoTH0VsZWt0
|
3111 |
+
cm9uaWsgQmlsZ2kgR3V2ZW5saWdpIEEuUy4xPDA6BgNVBAMTM2UtR3V2ZW4gS29rIEVsZWt0cm9u
|
3112 |
+
aWsgU2VydGlmaWthIEhpem1ldCBTYWdsYXlpY2lzaTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
3113 |
+
AQoCggEBAMMSIJ6wXgBljU5Gu4Bc6SwGl9XzcslwuedLZYDBS75+PNdUMZTe1RK6UxYC6lhj71vY
|
3114 |
+
8+0qGqpxSKPcEC1fX+tcS5yWCEIlKBHMilpiAVDV6wlTL/jDj/6z/P2douNffb7tC+Bg62nsM+3Y
|
3115 |
+
jfsSSYMAyYuXjDtzKjKzEve5TfL0TW3H5tYmNwjy2f1rXKPlSFxYvEK+A1qBuhw1DADT9SN+cTAI
|
3116 |
+
JjjcJRFHLfO6IxClv7wC90Nex/6wN1CZew+TzuZDLMN+DfIcQ2Zgy2ExR4ejT669VmxMvLz4Bcpk
|
3117 |
+
9Ok0oSy1c+HCPujIyTQlCFzz7abHlJ+tiEMl1+E5YP6sOVkCAwEAAaNCMEAwDgYDVR0PAQH/BAQD
|
3118 |
+
AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ/uRLOU1fqRTy7ZVZoEVtstxNulMA0GCSqG
|
3119 |
+
SIb3DQEBBQUAA4IBAQB/X7lTW2M9dTLn+sR0GstG30ZpHFLPqk/CaOv/gKlR6D1id4k9CnU58W5d
|
3120 |
+
F4dvaAXBlGzZXd/aslnLpRCKysw5zZ/rTt5S/wzw9JKp8mxTq5vSR6AfdPebmvEvFZ96ZDAYBzwq
|
3121 |
+
D2fK/A+JYZ1lpTzlvBNbCNvj/+27BrtqBrF6T2XGgv0enIu1De5Iu7i9qgi0+6N8y5/NkHZchpZ4
|
3122 |
+
Vwpm+Vganf2XKWDeEaaQHBkc7gGWIjQ0LpH5t8Qn0Xvmv/uARFoW5evg1Ao4vOSR49XrXMGs3xtq
|
3123 |
+
fJ7lddK2l4fbzIcrQzqECK+rPNv3PGYxhrCdU3nt+CPeQuMtgvEP5fqX
|
3124 |
+
-----END CERTIFICATE-----
|
3125 |
+
|
3126 |
+
GlobalSign Root CA - R3
|
3127 |
+
=======================
|
3128 |
+
-----BEGIN CERTIFICATE-----
|
3129 |
+
MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv
|
3130 |
+
YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh
|
3131 |
+
bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT
|
3132 |
+
aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln
|
3133 |
+
bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt
|
3134 |
+
iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ
|
3135 |
+
0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3
|
3136 |
+
rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl
|
3137 |
+
OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2
|
3138 |
+
xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
|
3139 |
+
FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7
|
3140 |
+
lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8
|
3141 |
+
EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E
|
3142 |
+
bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18
|
3143 |
+
YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r
|
3144 |
+
kpeDMdmztcpHWD9f
|
3145 |
+
-----END CERTIFICATE-----
|
3146 |
+
|
3147 |
+
TC TrustCenter Universal CA III
|
3148 |
+
===============================
|
3149 |
+
-----BEGIN CERTIFICATE-----
|
3150 |
+
MIID4TCCAsmgAwIBAgIOYyUAAQACFI0zFQLkbPQwDQYJKoZIhvcNAQEFBQAwezELMAkGA1UEBhMC
|
3151 |
+
REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVy
|
3152 |
+
IFVuaXZlcnNhbCBDQTEoMCYGA1UEAxMfVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIElJSTAe
|
3153 |
+
Fw0wOTA5MDkwODE1MjdaFw0yOTEyMzEyMzU5NTlaMHsxCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNU
|
3154 |
+
QyBUcnVzdENlbnRlciBHbWJIMSQwIgYDVQQLExtUQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0Ex
|
3155 |
+
KDAmBgNVBAMTH1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQSBJSUkwggEiMA0GCSqGSIb3DQEB
|
3156 |
+
AQUAA4IBDwAwggEKAoIBAQDC2pxisLlxErALyBpXsq6DFJmzNEubkKLF5+cvAqBNLaT6hdqbJYUt
|
3157 |
+
QCggbergvbFIgyIpRJ9Og+41URNzdNW88jBmlFPAQDYvDIRlzg9uwliT6CwLOunBjvvya8o84pxO
|
3158 |
+
juT5fdMnnxvVZ3iHLX8LR7PH6MlIfK8vzArZQe+f/prhsq75U7Xl6UafYOPfjdN/+5Z+s7Vy+Eut
|
3159 |
+
CHnNaYlAJ/Uqwa1D7KRTyGG299J5KmcYdkhtWyUB0SbFt1dpIxVbYYqt8Bst2a9c8SaQaanVDED1
|
3160 |
+
M4BDj5yjdipFtK+/fz6HP3bFzSreIMUWWMv5G/UPyw0RUmS40nZid4PxWJ//AgMBAAGjYzBhMB8G
|
3161 |
+
A1UdIwQYMBaAFFbn4VslQ4Dg9ozhcbyO5YAvxEjiMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
|
3162 |
+
BAQDAgEGMB0GA1UdDgQWBBRW5+FbJUOA4PaM4XG8juWAL8RI4jANBgkqhkiG9w0BAQUFAAOCAQEA
|
3163 |
+
g8ev6n9NCjw5sWi+e22JLumzCecYV42FmhfzdkJQEw/HkG8zrcVJYCtsSVgZ1OK+t7+rSbyUyKu+
|
3164 |
+
KGwWaODIl0YgoGhnYIg5IFHYaAERzqf2EQf27OysGh+yZm5WZ2B6dF7AbZc2rrUNXWZzwCUyRdhK
|
3165 |
+
BgePxLcHsU0GDeGl6/R1yrqc0L2z0zIkTO5+4nYES0lT2PLpVDP85XEfPRRclkvxOvIAu2y0+pZV
|
3166 |
+
CIgJwcyRGSmwIC3/yzikQOEXvnlhgP8HA4ZMTnsGnxGGjYnuJ8Tb4rwZjgvDwxPHLQNjO9Po5KIq
|
3167 |
+
woIIlBZU8O8fJ5AluA0OKBtHd0e9HKgl8ZS0Zg==
|
3168 |
+
-----END CERTIFICATE-----
|
3169 |
+
|
3170 |
+
Autoridad de Certificacion Firmaprofesional CIF A62634068
|
3171 |
+
=========================================================
|
3172 |
+
-----BEGIN CERTIFICATE-----
|
3173 |
+
MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA
|
3174 |
+
BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2
|
3175 |
+
MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw
|
3176 |
+
QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB
|
3177 |
+
NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD
|
3178 |
+
Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P
|
3179 |
+
B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY
|
3180 |
+
7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH
|
3181 |
+
ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI
|
3182 |
+
plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX
|
3183 |
+
MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX
|
3184 |
+
LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK
|
3185 |
+
bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU
|
3186 |
+
vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud
|
3187 |
+
EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH
|
3188 |
+
DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp
|
3189 |
+
cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA
|
3190 |
+
bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx
|
3191 |
+
ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx
|
3192 |
+
51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk
|
3193 |
+
R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP
|
3194 |
+
T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f
|
3195 |
+
Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl
|
3196 |
+
osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR
|
3197 |
+
crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR
|
3198 |
+
saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD
|
3199 |
+
KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi
|
3200 |
+
6Et8Vcad+qMUu2WFbm5PEn4KPJ2V
|
3201 |
+
-----END CERTIFICATE-----
|
3202 |
+
|
3203 |
+
Izenpe.com
|
3204 |
+
==========
|
3205 |
+
-----BEGIN CERTIFICATE-----
|
3206 |
+
MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG
|
3207 |
+
EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz
|
3208 |
+
MTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu
|
3209 |
+
QS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ
|
3210 |
+
03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK
|
3211 |
+
ClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU
|
3212 |
+
+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC
|
3213 |
+
PCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT
|
3214 |
+
OTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK
|
3215 |
+
F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK
|
3216 |
+
0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+
|
3217 |
+
0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB
|
3218 |
+
leStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID
|
3219 |
+
AQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+
|
3220 |
+
SVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG
|
3221 |
+
NjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx
|
3222 |
+
MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O
|
3223 |
+
BBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l
|
3224 |
+
Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga
|
3225 |
+
kEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q
|
3226 |
+
hT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs
|
3227 |
+
g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5
|
3228 |
+
aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5
|
3229 |
+
nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC
|
3230 |
+
ClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo
|
3231 |
+
Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z
|
3232 |
+
WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==
|
3233 |
+
-----END CERTIFICATE-----
|
3234 |
+
|
3235 |
+
Chambers of Commerce Root - 2008
|
3236 |
+
================================
|
3237 |
+
-----BEGIN CERTIFICATE-----
|
3238 |
+
MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYDVQQGEwJFVTFD
|
3239 |
+
MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv
|
3240 |
+
bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu
|
3241 |
+
QS4xKTAnBgNVBAMTIENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEy
|
3242 |
+
Mjk1MFoXDTM4MDczMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNl
|
3243 |
+
ZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQF
|
3244 |
+
EwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJl
|
3245 |
+
cnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
|
3246 |
+
AQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW928sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKA
|
3247 |
+
XuFixrYp4YFs8r/lfTJqVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorj
|
3248 |
+
h40G072QDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR5gN/
|
3249 |
+
ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfLZEFHcpOrUMPrCXZk
|
3250 |
+
NNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05aSd+pZgvMPMZ4fKecHePOjlO+Bd5g
|
3251 |
+
D2vlGts/4+EhySnB8esHnFIbAURRPHsl18TlUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331
|
3252 |
+
lubKgdaX8ZSD6e2wsWsSaR6s+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ
|
3253 |
+
0wlf2eOKNcx5Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj
|
3254 |
+
ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAxhduub+84Mxh2
|
3255 |
+
EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNVHQ4EFgQU+SSsD7K1+HnA+mCI
|
3256 |
+
G8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJ
|
3257 |
+
BgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNh
|
3258 |
+
bWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENh
|
3259 |
+
bWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiC
|
3260 |
+
CQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUH
|
3261 |
+
AgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAJASryI1
|
3262 |
+
wqM58C7e6bXpeHxIvj99RZJe6dqxGfwWPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH
|
3263 |
+
3qLPaYRgM+gQDROpI9CF5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbU
|
3264 |
+
RWpGqOt1glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaHFoI6
|
3265 |
+
M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2pSB7+R5KBWIBpih1
|
3266 |
+
YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MDxvbxrN8y8NmBGuScvfaAFPDRLLmF
|
3267 |
+
9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QGtjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcK
|
3268 |
+
zBIKinmwPQN/aUv0NCB9szTqjktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvG
|
3269 |
+
nrDQWzilm1DefhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg
|
3270 |
+
OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZd0jQ
|
3271 |
+
-----END CERTIFICATE-----
|
3272 |
+
|
3273 |
+
Global Chambersign Root - 2008
|
3274 |
+
==============================
|
3275 |
+
-----BEGIN CERTIFICATE-----
|
3276 |
+
MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYDVQQGEwJFVTFD
|
3277 |
+
MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv
|
3278 |
+
bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu
|
3279 |
+
QS4xJzAlBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMx
|
3280 |
+
NDBaFw0zODA3MzExMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUg
|
3281 |
+
Y3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ
|
3282 |
+
QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD
|
3283 |
+
aGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDf
|
3284 |
+
VtPkOpt2RbQT2//BthmLN0EYlVJH6xedKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXf
|
3285 |
+
XjaOcNFccUMd2drvXNL7G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0
|
3286 |
+
ZJJ0YPP2zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4ddPB
|
3287 |
+
/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyGHoiMvvKRhI9lNNgA
|
3288 |
+
TH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2Id3UwD2ln58fQ1DJu7xsepeY7s2M
|
3289 |
+
H/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3VyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfe
|
3290 |
+
Ox2YItaswTXbo6Al/3K1dh3ebeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSF
|
3291 |
+
HTynyQbehP9r6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh
|
3292 |
+
wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsogzCtLkykPAgMB
|
3293 |
+
AAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQWBBS5CcqcHtvTbDprru1U8VuT
|
3294 |
+
BjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDprru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UE
|
3295 |
+
BhMCRVUxQzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJm
|
3296 |
+
aXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJm
|
3297 |
+
aXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiCCQDJzdPp
|
3298 |
+
1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0
|
3299 |
+
dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAICIf3DekijZBZRG
|
3300 |
+
/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6
|
3301 |
+
ReAJ3spED8IXDneRRXozX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/s
|
3302 |
+
dZ7LoR/xfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVza2Mg
|
3303 |
+
9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yydYhz2rXzdpjEetrHH
|
3304 |
+
foUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMdSqlapskD7+3056huirRXhOukP9Du
|
3305 |
+
qqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9OAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETr
|
3306 |
+
P3iZ8ntxPjzxmKfFGBI/5rsoM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVq
|
3307 |
+
c5iJWzouE4gev8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z
|
3308 |
+
09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B
|
3309 |
+
-----END CERTIFICATE-----
|
3310 |
+
|
3311 |
+
Go Daddy Root Certificate Authority - G2
|
3312 |
+
========================================
|
3313 |
+
-----BEGIN CERTIFICATE-----
|
3314 |
+
MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
|
3315 |
+
B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu
|
3316 |
+
MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
|
3317 |
+
MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
|
3318 |
+
b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G
|
3319 |
+
A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
|
3320 |
+
hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq
|
3321 |
+
9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD
|
3322 |
+
+qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd
|
3323 |
+
fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl
|
3324 |
+
NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC
|
3325 |
+
MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9
|
3326 |
+
BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac
|
3327 |
+
vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r
|
3328 |
+
5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV
|
3329 |
+
N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
|
3330 |
+
LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1
|
3331 |
+
-----END CERTIFICATE-----
|
3332 |
+
|
3333 |
+
Starfield Root Certificate Authority - G2
|
3334 |
+
=========================================
|
3335 |
+
-----BEGIN CERTIFICATE-----
|
3336 |
+
MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
|
3337 |
+
B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s
|
3338 |
+
b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0
|
3339 |
+
eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw
|
3340 |
+
DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg
|
3341 |
+
VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB
|
3342 |
+
dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv
|
3343 |
+
W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs
|
3344 |
+
bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk
|
3345 |
+
N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf
|
3346 |
+
ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU
|
3347 |
+
JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
|
3348 |
+
AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol
|
3349 |
+
TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx
|
3350 |
+
4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw
|
3351 |
+
F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
|
3352 |
+
pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ
|
3353 |
+
c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
|
3354 |
+
-----END CERTIFICATE-----
|
3355 |
+
|
3356 |
+
Starfield Services Root Certificate Authority - G2
|
3357 |
+
==================================================
|
3358 |
+
-----BEGIN CERTIFICATE-----
|
3359 |
+
MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
|
3360 |
+
B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s
|
3361 |
+
b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl
|
3362 |
+
IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV
|
3363 |
+
BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT
|
3364 |
+
dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg
|
3365 |
+
Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
3366 |
+
AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2
|
3367 |
+
h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa
|
3368 |
+
hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP
|
3369 |
+
LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB
|
3370 |
+
rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw
|
3371 |
+
AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG
|
3372 |
+
SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP
|
3373 |
+
E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy
|
3374 |
+
xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
|
3375 |
+
iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza
|
3376 |
+
YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6
|
3377 |
+
-----END CERTIFICATE-----
|
3378 |
+
|
3379 |
+
AffirmTrust Commercial
|
3380 |
+
======================
|
3381 |
+
-----BEGIN CERTIFICATE-----
|
3382 |
+
MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS
|
3383 |
+
BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw
|
3384 |
+
MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly
|
3385 |
+
bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF
|
3386 |
+
AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb
|
3387 |
+
DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV
|
3388 |
+
C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6
|
3389 |
+
BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww
|
3390 |
+
MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV
|
3391 |
+
HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
|
3392 |
+
AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG
|
3393 |
+
hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi
|
3394 |
+
qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv
|
3395 |
+
0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh
|
3396 |
+
sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=
|
3397 |
+
-----END CERTIFICATE-----
|
3398 |
+
|
3399 |
+
AffirmTrust Networking
|
3400 |
+
======================
|
3401 |
+
-----BEGIN CERTIFICATE-----
|
3402 |
+
MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS
|
3403 |
+
BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw
|
3404 |
+
MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly
|
3405 |
+
bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF
|
3406 |
+
AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE
|
3407 |
+
Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI
|
3408 |
+
dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24
|
3409 |
+
/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb
|
3410 |
+
h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV
|
3411 |
+
HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
|
3412 |
+
AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu
|
3413 |
+
UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6
|
3414 |
+
12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23
|
3415 |
+
WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9
|
3416 |
+
/ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=
|
3417 |
+
-----END CERTIFICATE-----
|
3418 |
+
|
3419 |
+
AffirmTrust Premium
|
3420 |
+
===================
|
3421 |
+
-----BEGIN CERTIFICATE-----
|
3422 |
+
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
|
3446 |
+
-----END CERTIFICATE-----
|
3447 |
+
|
3448 |
+
AffirmTrust Premium ECC
|
3449 |
+
=======================
|
3450 |
+
-----BEGIN CERTIFICATE-----
|
3451 |
+
MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV
|
3452 |
+
BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx
|
3453 |
+
MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U
|
3454 |
+
cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA
|
3455 |
+
IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ
|
3456 |
+
N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW
|
3457 |
+
BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK
|
3458 |
+
BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X
|
3459 |
+
57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM
|
3460 |
+
eQ==
|
3461 |
+
-----END CERTIFICATE-----
|
3462 |
+
|
3463 |
+
Certum Trusted Network CA
|
3464 |
+
=========================
|
3465 |
+
-----BEGIN CERTIFICATE-----
|
3466 |
+
MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK
|
3467 |
+
ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv
|
3468 |
+
biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy
|
3469 |
+
MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU
|
3470 |
+
ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
|
3471 |
+
MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC
|
3472 |
+
AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC
|
3473 |
+
l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J
|
3474 |
+
J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4
|
3475 |
+
fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0
|
3476 |
+
cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB
|
3477 |
+
Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw
|
3478 |
+
DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj
|
3479 |
+
jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1
|
3480 |
+
mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj
|
3481 |
+
Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
|
3482 |
+
03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
|
3483 |
+
-----END CERTIFICATE-----
|
3484 |
+
|
3485 |
+
Certinomis - Autorité Racine
|
3486 |
+
=============================
|
3487 |
+
-----BEGIN CERTIFICATE-----
|
3488 |
+
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
|
3513 |
+
vgt2Fl43N+bYdJeimUV5
|
3514 |
+
-----END CERTIFICATE-----
|
3515 |
+
|
3516 |
+
Root CA Generalitat Valenciana
|
3517 |
+
==============================
|
3518 |
+
-----BEGIN CERTIFICATE-----
|
3519 |
+
MIIGizCCBXOgAwIBAgIEO0XlaDANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJFUzEfMB0GA1UE
|
3520 |
+
ChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290
|
3521 |
+
IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwHhcNMDEwNzA2MTYyMjQ3WhcNMjEwNzAxMTUyMjQ3
|
3522 |
+
WjBoMQswCQYDVQQGEwJFUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UE
|
3523 |
+
CxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwggEiMA0G
|
3524 |
+
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGKqtXETcvIorKA3Qdyu0togu8M1JAJke+WmmmO3I2
|
3525 |
+
F0zo37i7L3bhQEZ0ZQKQUgi0/6iMweDHiVYQOTPvaLRfX9ptI6GJXiKjSgbwJ/BXufjpTjJ3Cj9B
|
3526 |
+
ZPPrZe52/lSqfR0grvPXdMIKX/UIKFIIzFVd0g/bmoGlu6GzwZTNVOAydTGRGmKy3nXiz0+J2ZGQ
|
3527 |
+
D0EbtFpKd71ng+CT516nDOeB0/RSrFOyA8dEJvt55cs0YFAQexvba9dHq198aMpunUEDEO5rmXte
|
3528 |
+
JajCq+TA81yc477OMUxkHl6AovWDfgzWyoxVjr7gvkkHD6MkQXpYHYTqWBLI4bft75PelAgxAgMB
|
3529 |
+
AAGjggM7MIIDNzAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnBraS5n
|
3530 |
+
dmEuZXMwEgYDVR0TAQH/BAgwBgEB/wIBAjCCAjQGA1UdIASCAiswggInMIICIwYKKwYBBAG/VQIB
|
3531 |
+
ADCCAhMwggHoBggrBgEFBQcCAjCCAdoeggHWAEEAdQB0AG8AcgBpAGQAYQBkACAAZABlACAAQwBl
|
3532 |
+
AHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAFIAYQDtAHoAIABkAGUAIABsAGEAIABHAGUAbgBlAHIA
|
3533 |
+
YQBsAGkAdABhAHQAIABWAGEAbABlAG4AYwBpAGEAbgBhAC4ADQAKAEwAYQAgAEQAZQBjAGwAYQBy
|
3534 |
+
AGEAYwBpAPMAbgAgAGQAZQAgAFAAcgDhAGMAdABpAGMAYQBzACAAZABlACAAQwBlAHIAdABpAGYA
|
3535 |
+
aQBjAGEAYwBpAPMAbgAgAHEAdQBlACAAcgBpAGcAZQAgAGUAbAAgAGYAdQBuAGMAaQBvAG4AYQBt
|
3536 |
+
AGkAZQBuAHQAbwAgAGQAZQAgAGwAYQAgAHAAcgBlAHMAZQBuAHQAZQAgAEEAdQB0AG8AcgBpAGQA
|
3537 |
+
YQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAHMAZQAgAGUAbgBjAHUAZQBu
|
3538 |
+
AHQAcgBhACAAZQBuACAAbABhACAAZABpAHIAZQBjAGMAaQDzAG4AIAB3AGUAYgAgAGgAdAB0AHAA
|
3539 |
+
OgAvAC8AdwB3AHcALgBwAGsAaQAuAGcAdgBhAC4AZQBzAC8AYwBwAHMwJQYIKwYBBQUHAgEWGWh0
|
3540 |
+
dHA6Ly93d3cucGtpLmd2YS5lcy9jcHMwHQYDVR0OBBYEFHs100DSHHgZZu90ECjcPk+yeAT8MIGV
|
3541 |
+
BgNVHSMEgY0wgYqAFHs100DSHHgZZu90ECjcPk+yeAT8oWykajBoMQswCQYDVQQGEwJFUzEfMB0G
|
3542 |
+
A1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5S
|
3543 |
+
b290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmGCBDtF5WgwDQYJKoZIhvcNAQEFBQADggEBACRh
|
3544 |
+
TvW1yEICKrNcda3FbcrnlD+laJWIwVTAEGmiEi8YPyVQqHxK6sYJ2fR1xkDar1CdPaUWu20xxsdz
|
3545 |
+
Ckj+IHLtb8zog2EWRpABlUt9jppSCS/2bxzkoXHPjCpaF3ODR00PNvsETUlR4hTJZGH71BTg9J63
|
3546 |
+
NI8KJr2XXPR5OkowGcytT6CYirQxlyric21+eLj4iIlPsSKRZEv1UN4D2+XFducTZnV+ZfsBn5OH
|
3547 |
+
iJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmCIoaZM3Fa6hlXPZHNqcCjbgcTpsnt
|
3548 |
+
+GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM=
|
3549 |
+
-----END CERTIFICATE-----
|
3550 |
+
|
3551 |
+
A-Trust-nQual-03
|
3552 |
+
================
|
3553 |
+
-----BEGIN CERTIFICATE-----
|
3554 |
+
MIIDzzCCAregAwIBAgIDAWweMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYDVQQGEwJBVDFIMEYGA1UE
|
3555 |
+
Cgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBpbSBlbGVrdHIuIERhdGVudmVy
|
3556 |
+
a2VociBHbWJIMRkwFwYDVQQLDBBBLVRydXN0LW5RdWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5R
|
3557 |
+
dWFsLTAzMB4XDTA1MDgxNzIyMDAwMFoXDTE1MDgxNzIyMDAwMFowgY0xCzAJBgNVBAYTAkFUMUgw
|
3558 |
+
RgYDVQQKDD9BLVRydXN0IEdlcy4gZi4gU2ljaGVyaGVpdHNzeXN0ZW1lIGltIGVsZWt0ci4gRGF0
|
3559 |
+
ZW52ZXJrZWhyIEdtYkgxGTAXBgNVBAsMEEEtVHJ1c3QtblF1YWwtMDMxGTAXBgNVBAMMEEEtVHJ1
|
3560 |
+
c3QtblF1YWwtMDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtPWFuA/OQO8BBC4SA
|
3561 |
+
zewqo51ru27CQoT3URThoKgtUaNR8t4j8DRE/5TrzAUjlUC5B3ilJfYKvUWG6Nm9wASOhURh73+n
|
3562 |
+
yfrBJcyFLGM/BWBzSQXgYHiVEEvc+RFZznF/QJuKqiTfC0Li21a8StKlDJu3Qz7dg9MmEALP6iPE
|
3563 |
+
SU7l0+m0iKsMrmKS1GWH2WrX9IWf5DMiJaXlyDO6w8dB3F/GaswADm0yqLaHNgBid5seHzTLkDx4
|
3564 |
+
iHQF63n1k3Flyp3HaxgtPVxO59X4PzF9j4fsCiIvI+n+u33J4PTs63zEsMMtYrWacdaxaujs2e3V
|
3565 |
+
cuy+VwHOBVWf3tFgiBCzAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0OBAoECERqlWdV
|
3566 |
+
eRFPMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAVdRU0VlIXLOThaq/Yy/kgM40
|
3567 |
+
ozRiPvbY7meIMQQDbwvUB/tOdQ/TLtPAF8fGKOwGDREkDg6lXb+MshOWcdzUzg4NCmgybLlBMRmr
|
3568 |
+
sQd7TZjTXLDR8KdCoLXEjq/+8T/0709GAHbrAvv5ndJAlseIOrifEXnzgGWovR/TeIGgUUw3tKZd
|
3569 |
+
JXDRZslo+S4RFGjxVJgIrCaSD96JntT6s3kr0qN51OyLrIdTaEJMUVF0HhsnLuP1Hyl0Te2v9+GS
|
3570 |
+
mYHovjrHF1D2t8b8m7CKa9aIA5GPBnc6hQLdmNVDeD/GMBWsm2vLV7eJUYs66MmEDNuxUCAKGkq6
|
3571 |
+
ahq97BvIxYSazQ==
|
3572 |
+
-----END CERTIFICATE-----
|
3573 |
+
|
3574 |
+
TWCA Root Certification Authority
|
3575 |
+
=================================
|
3576 |
+
-----BEGIN CERTIFICATE-----
|
3577 |
+
MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ
|
3578 |
+
VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh
|
3579 |
+
dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG
|
3580 |
+
EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB
|
3581 |
+
IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
|
3582 |
+
AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx
|
3583 |
+
QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC
|
3584 |
+
oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP
|
3585 |
+
4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r
|
3586 |
+
y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB
|
3587 |
+
BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG
|
3588 |
+
9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC
|
3589 |
+
mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW
|
3590 |
+
QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY
|
3591 |
+
T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny
|
3592 |
+
Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==
|
3593 |
+
-----END CERTIFICATE-----
|
3594 |
+
|
3595 |
+
Security Communication RootCA2
|
3596 |
+
==============================
|
3597 |
+
-----BEGIN CERTIFICATE-----
|
3598 |
+
MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc
|
3599 |
+
U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh
|
3600 |
+
dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC
|
3601 |
+
SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy
|
3602 |
+
aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
3603 |
+
ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++
|
3604 |
+
+T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R
|
3605 |
+
3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV
|
3606 |
+
spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K
|
3607 |
+
EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8
|
3608 |
+
QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB
|
3609 |
+
CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj
|
3610 |
+
u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk
|
3611 |
+
3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q
|
3612 |
+
tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29
|
3613 |
+
mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
|
3614 |
+
-----END CERTIFICATE-----
|
3615 |
+
|
3616 |
+
EC-ACC
|
3617 |
+
======
|
3618 |
+
-----BEGIN CERTIFICATE-----
|
3619 |
+
MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE
|
3620 |
+
BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w
|
3621 |
+
ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD
|
3622 |
+
VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE
|
3623 |
+
CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT
|
3624 |
+
BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7
|
3625 |
+
MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt
|
3626 |
+
SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl
|
3627 |
+
Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh
|
3628 |
+
cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND
|
3629 |
+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK
|
3630 |
+
w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT
|
3631 |
+
ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4
|
3632 |
+
HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a
|
3633 |
+
E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw
|
3634 |
+
0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E
|
3635 |
+
BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD
|
3636 |
+
VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0
|
3637 |
+
Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l
|
3638 |
+
dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ
|
3639 |
+
lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa
|
3640 |
+
Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe
|
3641 |
+
l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2
|
3642 |
+
E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D
|
3643 |
+
5EI=
|
3644 |
+
-----END CERTIFICATE-----
|
3645 |
+
|
3646 |
+
Hellenic Academic and Research Institutions RootCA 2011
|
3647 |
+
=======================================================
|
3648 |
+
-----BEGIN CERTIFICATE-----
|
3649 |
+
MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1IxRDBCBgNVBAoT
|
3650 |
+
O0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9y
|
3651 |
+
aXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z
|
3652 |
+
IFJvb3RDQSAyMDExMB4XDTExMTIwNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYT
|
3653 |
+
AkdSMUQwQgYDVQQKEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z
|
3654 |
+
IENlcnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNo
|
3655 |
+
IEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
3656 |
+
AKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPzdYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI
|
3657 |
+
1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa
|
3658 |
+
71HFK9+WXesyHgLacEnsbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u
|
3659 |
+
8yBRQlqD75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSPFEDH
|
3660 |
+
3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNVHRMBAf8EBTADAQH/
|
3661 |
+
MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp5dgTBCPuQSUwRwYDVR0eBEAwPqA8
|
3662 |
+
MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQub3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQu
|
3663 |
+
b3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVt
|
3664 |
+
XdMiKahsog2p6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8
|
3665 |
+
TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7dIsXRSZMFpGD
|
3666 |
+
/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8AcysNnq/onN694/BtZqhFLKPM58N
|
3667 |
+
7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXIl7WdmplNsDz4SgCbZN2fOUvRJ9e4
|
3668 |
+
-----END CERTIFICATE-----
|
3669 |
+
|
3670 |
+
Actalis Authentication Root CA
|
3671 |
+
==============================
|
3672 |
+
-----BEGIN CERTIFICATE-----
|
3673 |
+
MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM
|
3674 |
+
BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE
|
3675 |
+
AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky
|
3676 |
+
MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz
|
3677 |
+
IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290
|
3678 |
+
IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ
|
3679 |
+
wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa
|
3680 |
+
by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6
|
3681 |
+
zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f
|
3682 |
+
YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2
|
3683 |
+
oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l
|
3684 |
+
EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7
|
3685 |
+
hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8
|
3686 |
+
EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5
|
3687 |
+
jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY
|
3688 |
+
iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt
|
3689 |
+
ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI
|
3690 |
+
WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0
|
3691 |
+
JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx
|
3692 |
+
K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+
|
3693 |
+
Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC
|
3694 |
+
4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo
|
3695 |
+
2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz
|
3696 |
+
lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem
|
3697 |
+
OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9
|
3698 |
+
vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==
|
3699 |
+
-----END CERTIFICATE-----
|
3700 |
+
|
3701 |
+
Trustis FPS Root CA
|
3702 |
+
===================
|
3703 |
+
-----BEGIN CERTIFICATE-----
|
3704 |
+
MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQG
|
3705 |
+
EwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQLExNUcnVzdGlzIEZQUyBSb290
|
3706 |
+
IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTExMzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNV
|
3707 |
+
BAoTD1RydXN0aXMgTGltaXRlZDEcMBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJ
|
3708 |
+
KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQ
|
3709 |
+
RUN+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihHiTHcDnlk
|
3710 |
+
H5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjjvSkCqPoc4Vu5g6hBSLwa
|
3711 |
+
cY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zt
|
3712 |
+
o3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlBOrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEA
|
3713 |
+
AaNTMFEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAd
|
3714 |
+
BgNVHQ4EFgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01GX2c
|
3715 |
+
GE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmWzaD+vkAMXBJV+JOC
|
3716 |
+
yinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP41BIy+Q7DsdwyhEQsb8tGD+pmQQ9P
|
3717 |
+
8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZEf1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHV
|
3718 |
+
l/9D7S3B2l0pKoU/rGXuhg8FjZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYl
|
3719 |
+
iB6XzCGcKQENZetX2fNXlrtIzYE=
|
3720 |
+
-----END CERTIFICATE-----
|
3721 |
+
|
3722 |
+
StartCom Certification Authority
|
3723 |
+
================================
|
3724 |
+
-----BEGIN CERTIFICATE-----
|
3725 |
+
MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN
|
3726 |
+
U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu
|
3727 |
+
ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0
|
3728 |
+
NjM3WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk
|
3729 |
+
LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg
|
3730 |
+
U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
|
3731 |
+
ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y
|
3732 |
+
o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/
|
3733 |
+
Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d
|
3734 |
+
eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt
|
3735 |
+
2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z
|
3736 |
+
6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ
|
3737 |
+
osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/
|
3738 |
+
untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc
|
3739 |
+
UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT
|
3740 |
+
37uMdBNSSwIDAQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
|
3741 |
+
VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFulF2mHMMo0aEPQ
|
3742 |
+
Qa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCCATgwLgYIKwYBBQUHAgEWImh0
|
3743 |
+
dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cu
|
3744 |
+
c3RhcnRzc2wuY29tL2ludGVybWVkaWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENv
|
3745 |
+
bW1lcmNpYWwgKFN0YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0
|
3746 |
+
aGUgc2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0aWZpY2F0
|
3747 |
+
aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93d3cuc3RhcnRzc2wuY29t
|
3748 |
+
L3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBG
|
3749 |
+
cmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5
|
3750 |
+
fPGFf59Jb2vKXfuM/gTFwWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWm
|
3751 |
+
N3PH/UvSTa0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst0OcN
|
3752 |
+
Org+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNcpRJvkrKTlMeIFw6T
|
3753 |
+
tn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKlCcWw0bdT82AUuoVpaiF8H3VhFyAX
|
3754 |
+
e2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVFP0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA
|
3755 |
+
2MFrLH9ZXF2RsXAiV+uKa0hK1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBs
|
3756 |
+
HvUwyKMQ5bLmKhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE
|
3757 |
+
JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ8dCAWZvLMdib
|
3758 |
+
D4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnmfyWl8kgAwKQB2j8=
|
3759 |
+
-----END CERTIFICATE-----
|
3760 |
+
|
3761 |
+
StartCom Certification Authority G2
|
3762 |
+
===================================
|
3763 |
+
-----BEGIN CERTIFICATE-----
|
3764 |
+
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
|
3788 |
+
obp573PYtlNXLfbQ4ddI
|
3789 |
+
-----END CERTIFICATE-----
|
3790 |
+
|
3791 |
+
Buypass Class 2 Root CA
|
3792 |
+
=======================
|
3793 |
+
-----BEGIN CERTIFICATE-----
|
3794 |
+
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
|
3818 |
+
rJgWVqA=
|
3819 |
+
-----END CERTIFICATE-----
|
3820 |
+
|
3821 |
+
Buypass Class 3 Root CA
|
3822 |
+
=======================
|
3823 |
+
-----BEGIN CERTIFICATE-----
|
3824 |
+
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
|
3848 |
+
Cp/HuZc=
|
3849 |
+
-----END CERTIFICATE-----
|
3850 |
+
|
3851 |
+
TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı
|
3852 |
+
======================================================
|
3853 |
+
-----BEGIN CERTIFICATE-----
|
3854 |
+
MIIEPTCCAyWgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvzE/MD0GA1UEAww2VMOcUktUUlVTVCBF
|
3855 |
+
bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP
|
3856 |
+
MA0GA1UEBwwGQW5rYXJhMV4wXAYDVQQKDFVUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg
|
3857 |
+
QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgQXJhbMSxayAyMDA3MB4X
|
3858 |
+
DTA3MTIyNTE4MzcxOVoXDTE3MTIyMjE4MzcxOVowgb8xPzA9BgNVBAMMNlTDnFJLVFJVU1QgRWxl
|
3859 |
+
a3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTELMAkGA1UEBhMCVFIxDzAN
|
3860 |
+
BgNVBAcMBkFua2FyYTFeMFwGA1UECgxVVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp
|
3861 |
+
bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4gKGMpIEFyYWzEsWsgMjAwNzCCASIw
|
3862 |
+
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKu3PgqMyKVYFeaK7yc9SrToJdPNM8Ig3BnuiD9N
|
3863 |
+
YvDdE3ePYakqtdTyuTFYKTsvP2qcb3N2Je40IIDu6rfwxArNK4aUyeNgsURSsloptJGXg9i3phQv
|
3864 |
+
KUmi8wUG+7RP2qFsmmaf8EMJyupyj+sA1zU511YXRxcw9L6/P8JorzZAwan0qafoEGsIiveGHtya
|
3865 |
+
KhUG9qPw9ODHFNRRf8+0222vR5YXm3dx2KdxnSQM9pQ/hTEST7ruToK4uT6PIzdezKKqdfcYbwnT
|
3866 |
+
rqdUKDT74eA7YH2gvnmJhsifLfkKS8RQouf9eRbHegsYz85M733WB2+Y8a+xwXrXgTW4qhe04MsC
|
3867 |
+
AwEAAaNCMEAwHQYDVR0OBBYEFCnFkKslrxHkYb+j/4hhkeYO/pyBMA4GA1UdDwEB/wQEAwIBBjAP
|
3868 |
+
BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAQDdr4Ouwo0RSVgrESLFF6QSU2TJ/s
|
3869 |
+
Px+EnWVUXKgWAkD6bho3hO9ynYYKVZ1WKKxmLNA6VpM0ByWtCLCPyA8JWcqdmBzlVPi5RX9ql2+I
|
3870 |
+
aE1KBiY3iAIOtsbWcpnOa3faYjGkVh+uX4132l32iPwa2Z61gfAyuOOI0JzzaqC5mxRZNTZPz/OO
|
3871 |
+
Xl0XrRWV2N2y1RVuAE6zS89mlOTgzbUF2mNXi+WzqtvALhyQRNsaXRik7r4EW5nVcV9VZWRi1aKb
|
3872 |
+
BFmGyGJ353yCRWo9F7/snXUMrqNvWtMvmDb08PUZqxFdyKbjKlhqQgnDvZImZjINXQhVdP+MmNAK
|
3873 |
+
poRq0Tl9
|
3874 |
+
-----END CERTIFICATE-----
|
3875 |
+
|
3876 |
+
T-TeleSec GlobalRoot Class 3
|
3877 |
+
============================
|
3878 |
+
-----BEGIN CERTIFICATE-----
|
3879 |
+
MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM
|
3880 |
+
IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU
|
3881 |
+
cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx
|
3882 |
+
MDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz
|
3883 |
+
dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD
|
3884 |
+
ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3
|
3885 |
+
DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK
|
3886 |
+
9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU
|
3887 |
+
NpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF
|
3888 |
+
iP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W
|
3889 |
+
0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA
|
3890 |
+
MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr
|
3891 |
+
AyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb
|
3892 |
+
fsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT
|
3893 |
+
ucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h
|
3894 |
+
P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml
|
3895 |
+
e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw==
|
3896 |
+
-----END CERTIFICATE-----
|
3897 |
+
|
3898 |
+
EE Certification Centre Root CA
|
3899 |
+
===============================
|
3900 |
+
-----BEGIN CERTIFICATE-----
|
3901 |
+
MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG
|
3902 |
+
EwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEoMCYGA1UEAwwfRUUgQ2Vy
|
3903 |
+
dGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIw
|
3904 |
+
MTAxMDMwMTAxMDMwWhgPMjAzMDEyMTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlB
|
3905 |
+
UyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRy
|
3906 |
+
ZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IB
|
3907 |
+
DwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUyeuuOF0+W2Ap7kaJjbMeM
|
3908 |
+
TC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvObntl8jixwKIy72KyaOBhU8E2lf/slLo2
|
3909 |
+
rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIwWFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw
|
3910 |
+
93X2PaRka9ZP585ArQ/dMtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtN
|
3911 |
+
P2MbRMNE1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYDVR0T
|
3912 |
+
AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/zQas8fElyalL1BSZ
|
3913 |
+
MEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEF
|
3914 |
+
BQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEFBQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+Rj
|
3915 |
+
xY6hUFaTlrg4wCQiZrxTFGGVv9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqM
|
3916 |
+
lIpPnTX/dqQGE5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u
|
3917 |
+
uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIWiAYLtqZLICjU
|
3918 |
+
3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/vGVCJYMzpJJUPwssd8m92kMfM
|
3919 |
+
dcGWxZ0=
|
3920 |
+
-----END CERTIFICATE-----
|
trunk/includes/Dropbox/OAuth/Storage/Encrypter.php
ADDED
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* This class provides the functionality to encrypt
|
5 |
+
* and decrypt access tokens stored by the application
|
6 |
+
* @author Ben Tadiar <ben@handcraftedbyben.co.uk>
|
7 |
+
* @link https://github.com/benthedesigner/dropbox
|
8 |
+
* @package Dropbox\Oauth
|
9 |
+
* @subpackage Storage
|
10 |
+
*/
|
11 |
+
|
12 |
+
class Dropbox_Encrypter
|
13 |
+
{
|
14 |
+
// Encryption settings - default settings yield encryption to AES (256-bit) standard
|
15 |
+
// @todo Provide PHPDOC for each class constant
|
16 |
+
const CIPHER = MCRYPT_RIJNDAEL_128;
|
17 |
+
const MODE = MCRYPT_MODE_CBC;
|
18 |
+
const KEY_SIZE = 32;
|
19 |
+
const IV_SIZE = 16;
|
20 |
+
const IV_SOURCE = MCRYPT_DEV_URANDOM;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Encryption key
|
24 |
+
* @var null|string
|
25 |
+
*/
|
26 |
+
private $key = null;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Check Mcrypt is loaded and set the encryption key
|
30 |
+
* @param string $key
|
31 |
+
* @return void
|
32 |
+
*/
|
33 |
+
public function __construct($key)
|
34 |
+
{
|
35 |
+
if (!extension_loaded('mcrypt')) {
|
36 |
+
throw new Dropbox_Exception('The storage encrypter requires the MCrypt extension');
|
37 |
+
} elseif (($length = mb_strlen($key, '8bit')) !== self::KEY_SIZE) {
|
38 |
+
throw new Dropbox_Exception('Expecting a ' . self::KEY_SIZE . ' byte key, got ' . $length);
|
39 |
+
} else {
|
40 |
+
// Set the encryption key
|
41 |
+
$this->key = $key;
|
42 |
+
}
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Encrypt the OAuth token
|
47 |
+
* @param \stdClass $token Serialized token object
|
48 |
+
* @return string
|
49 |
+
*/
|
50 |
+
public function encrypt($token)
|
51 |
+
{
|
52 |
+
$iv = mcrypt_create_iv(self::IV_SIZE, self::IV_SOURCE);
|
53 |
+
$cipherText = @mcrypt_encrypt(self::CIPHER, $this->key, $token, self::MODE, $iv);
|
54 |
+
return base64_encode($iv . $cipherText);
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Decrypt the ciphertext
|
59 |
+
* @param string $cipherText
|
60 |
+
* @return object \stdClass Unserialized token
|
61 |
+
*/
|
62 |
+
public function decrypt($cipherText)
|
63 |
+
{
|
64 |
+
$cipherText = base64_decode($cipherText);
|
65 |
+
$iv = substr($cipherText, 0, self::IV_SIZE);
|
66 |
+
$cipherText = substr($cipherText, self::IV_SIZE);
|
67 |
+
$token = @mcrypt_decrypt(self::CIPHER, $this->key, $cipherText, self::MODE, $iv);
|
68 |
+
return $token;
|
69 |
+
}
|
70 |
+
}
|
trunk/includes/Dropbox/OAuth/Storage/StorageInterface.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* OAuth storage handler interface
|
5 |
+
* @author Ben Tadiar <ben@handcraftedbyben.co.uk>
|
6 |
+
* @link https://github.com/benthedesigner/dropbox
|
7 |
+
* @package Dropbox\OAuth
|
8 |
+
* @subpackage Storage
|
9 |
+
*/
|
10 |
+
|
11 |
+
interface Dropbox_StorageInterface
|
12 |
+
{
|
13 |
+
/**
|
14 |
+
* Get a token by type
|
15 |
+
* @param string $type Token type to retrieve
|
16 |
+
*/
|
17 |
+
public function get($type);
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Set a token by type
|
21 |
+
* @param \stdClass $token Token object to set
|
22 |
+
* @param string $type Token type
|
23 |
+
*/
|
24 |
+
public function set($token, $type);
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Delete tokens for the current session/user
|
28 |
+
*/
|
29 |
+
public function delete();
|
30 |
+
}
|
trunk/includes/Dropbox/OAuth/Storage/WordPress.php
ADDED
@@ -0,0 +1,126 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* OAuth storage handler using WordPress options
|
5 |
+
* This can only be used if you have a WordPress environment loaded, such that the (get|update|delete)_option functions are available
|
6 |
+
* See an example usage in http://wordpress.org/extend/plugins/updraftplus
|
7 |
+
* @author David Anderson <david@wordshell.net>
|
8 |
+
* @link http://wordshell.net
|
9 |
+
* @package Dropbox\Oauth
|
10 |
+
* @subpackage Storage
|
11 |
+
*/
|
12 |
+
|
13 |
+
class Dropbox_WordPress implements Dropbox_StorageInterface
|
14 |
+
{
|
15 |
+
/**
|
16 |
+
* Option name
|
17 |
+
* @var string
|
18 |
+
*/
|
19 |
+
protected $option_name_prefix = 'dropbox_token';
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Encyption object
|
23 |
+
* @var Encrypter|null
|
24 |
+
*/
|
25 |
+
protected $encrypter = null;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Check if an instance of the encrypter is passed, set the encryption object
|
29 |
+
* @return void
|
30 |
+
*/
|
31 |
+
public function __construct(Dropbox_Encrypter $encrypter = null, $option_name_prefix = 'dropbox_token')
|
32 |
+
{
|
33 |
+
if ($encrypter instanceof Dropbox_Encrypter) {
|
34 |
+
$this->encrypter = $encrypter;
|
35 |
+
}
|
36 |
+
|
37 |
+
$this->option_name_prefix = $option_name_prefix;
|
38 |
+
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Get an OAuth token from the database
|
43 |
+
* If the encryption object is set then decrypt the token before returning
|
44 |
+
* @param string $type Token type to retrieve
|
45 |
+
* @return array|bool
|
46 |
+
*/
|
47 |
+
public function get($type)
|
48 |
+
{
|
49 |
+
if ($type != 'request_token' && $type != 'access_token') {
|
50 |
+
throw new Dropbox_Exception("Expected a type of either 'request_token' or 'access_token', got '$type'");
|
51 |
+
} else {
|
52 |
+
if (false !== ($gettoken = UpdraftPlus_Options::get_updraft_option($this->option_name_prefix.$type))) {
|
53 |
+
$token = $this->decrypt($gettoken);
|
54 |
+
return $token;
|
55 |
+
}
|
56 |
+
return false;
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Set an OAuth token in the database by type
|
62 |
+
* If the encryption object is set then encrypt the token before storing
|
63 |
+
* @param \stdClass Token object to set
|
64 |
+
* @param string $type Token type
|
65 |
+
* @return void
|
66 |
+
*/
|
67 |
+
public function set($token, $type)
|
68 |
+
{
|
69 |
+
if ($type != 'request_token' && $type != 'access_token') {
|
70 |
+
throw new Dropbox_Exception("Expected a type of either 'request_token' or 'access_token', got '$type'");
|
71 |
+
} else {
|
72 |
+
$token = $this->encrypt($token);
|
73 |
+
UpdraftPlus_Options::update_updraft_option($this->option_name_prefix.$type, $token);
|
74 |
+
}
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Delete the request and access tokens currently stored in the database
|
79 |
+
* @return bool
|
80 |
+
*/
|
81 |
+
public function delete()
|
82 |
+
{
|
83 |
+
UpdraftPlus_Options::delete_updraft_option($this->option_name_prefix.'request_token');
|
84 |
+
UpdraftPlus_Options::delete_updraft_option($this->option_name_prefix.'access_token');
|
85 |
+
return true;
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Use the Encrypter to encrypt a token and return it
|
90 |
+
* If there is not encrypter object, return just the
|
91 |
+
* serialized token object for storage
|
92 |
+
* @param stdClass $token OAuth token to encrypt
|
93 |
+
* @return stdClass|string
|
94 |
+
*/
|
95 |
+
protected function encrypt($token)
|
96 |
+
{
|
97 |
+
// Serialize the token object
|
98 |
+
$token = serialize($token);
|
99 |
+
|
100 |
+
// Encrypt the token if there is an Encrypter instance
|
101 |
+
if ($this->encrypter instanceof Dropbox_Encrypter) {
|
102 |
+
$token = $this->encrypter->encrypt($token);
|
103 |
+
}
|
104 |
+
|
105 |
+
// Return the token
|
106 |
+
return $token;
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Decrypt a token using the Encrypter object and return it
|
111 |
+
* If there is no Encrypter object, assume the token was stored
|
112 |
+
* serialized and return the unserialized token object
|
113 |
+
* @param stdClass $token OAuth token to encrypt
|
114 |
+
* @return stdClass|string
|
115 |
+
*/
|
116 |
+
protected function decrypt($token)
|
117 |
+
{
|
118 |
+
// Decrypt the token if there is an Encrypter instance
|
119 |
+
if ($this->encrypter instanceof Dropbox_Encrypter) {
|
120 |
+
$token = $this->encrypter->decrypt($token);
|
121 |
+
}
|
122 |
+
|
123 |
+
// Return the unserialized token
|
124 |
+
return @unserialize($token);
|
125 |
+
}
|
126 |
+
}
|
trunk/includes/Rijndael.php
ADDED
@@ -0,0 +1,1424 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 |
+
|
4 |
+
/**
|
5 |
+
* Pure-PHP implementation of Rijndael.
|
6 |
+
*
|
7 |
+
* Does not use mcrypt, even when available, for reasons that are explained below.
|
8 |
+
*
|
9 |
+
* PHP versions 4 and 5
|
10 |
+
*
|
11 |
+
* If {@link Crypt_Rijndael::setBlockLength() setBlockLength()} isn't called, it'll be assumed to be 128 bits. If
|
12 |
+
* {@link Crypt_Rijndael::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
|
13 |
+
* {@link Crypt_Rijndael::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's
|
14 |
+
* 136-bits it'll be null-padded to 160-bits and 160 bits will be the key length until
|
15 |
+
* {@link Crypt_Rijndael::setKey() setKey()} is called, again, at which point, it'll be recalculated.
|
16 |
+
*
|
17 |
+
* Not all Rijndael implementations may support 160-bits or 224-bits as the block length / key length. mcrypt, for example,
|
18 |
+
* does not. AES, itself, only supports block lengths of 128 and key lengths of 128, 192, and 256.
|
19 |
+
* {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=10 Rijndael-ammended.pdf#page=10} defines the
|
20 |
+
* algorithm for block lengths of 192 and 256 but not for block lengths / key lengths of 160 and 224. Indeed, 160 and 224
|
21 |
+
* are first defined as valid key / block lengths in
|
22 |
+
* {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=44 Rijndael-ammended.pdf#page=44}:
|
23 |
+
* Extensions: Other block and Cipher Key lengths.
|
24 |
+
*
|
25 |
+
* {@internal The variable names are the same as those in
|
26 |
+
* {@link http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf#page=10 fips-197.pdf#page=10}.}}
|
27 |
+
*
|
28 |
+
* Here's a short example of how to use this library:
|
29 |
+
* <code>
|
30 |
+
* <?php
|
31 |
+
* include('Crypt/Rijndael.php');
|
32 |
+
*
|
33 |
+
* $rijndael = new Crypt_Rijndael();
|
34 |
+
*
|
35 |
+
* $rijndael->setKey('abcdefghijklmnop');
|
36 |
+
*
|
37 |
+
* $size = 10 * 1024;
|
38 |
+
* $plaintext = '';
|
39 |
+
* for ($i = 0; $i < $size; $i++) {
|
40 |
+
* $plaintext.= 'a';
|
41 |
+
* }
|
42 |
+
*
|
43 |
+
* echo $rijndael->decrypt($rijndael->encrypt($plaintext));
|
44 |
+
* ?>
|
45 |
+
* </code>
|
46 |
+
*
|
47 |
+
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
48 |
+
* of this software and associated documentation files (the "Software"), to deal
|
49 |
+
* in the Software without restriction, including without limitation the rights
|
50 |
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
51 |
+
* copies of the Software, and to permit persons to whom the Software is
|
52 |
+
* furnished to do so, subject to the following conditions:
|
53 |
+
*
|
54 |
+
* The above copyright notice and this permission notice shall be included in
|
55 |
+
* all copies or substantial portions of the Software.
|
56 |
+
*
|
57 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
58 |
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
59 |
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
60 |
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
61 |
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
62 |
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
63 |
+
* THE SOFTWARE.
|
64 |
+
*
|
65 |
+
* @category Crypt
|
66 |
+
* @package Crypt_Rijndael
|
67 |
+
* @author Jim Wigginton <terrafrost@php.net>
|
68 |
+
* @copyright MMVIII Jim Wigginton
|
69 |
+
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
70 |
+
* @version $Id: Rijndael.php,v 1.12 2010/02/09 06:10:26 terrafrost Exp $
|
71 |
+
* @link http://phpseclib.sourceforge.net
|
72 |
+
*/
|
73 |
+
|
74 |
+
/**#@+
|
75 |
+
* @access public
|
76 |
+
* @see Crypt_Rijndael::encrypt()
|
77 |
+
* @see Crypt_Rijndael::decrypt()
|
78 |
+
*/
|
79 |
+
/**
|
80 |
+
* Encrypt / decrypt using the Counter mode.
|
81 |
+
*
|
82 |
+
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
|
83 |
+
*
|
84 |
+
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
|
85 |
+
*/
|
86 |
+
define('CRYPT_RIJNDAEL_MODE_CTR', -1);
|
87 |
+
/**
|
88 |
+
* Encrypt / decrypt using the Electronic Code Book mode.
|
89 |
+
*
|
90 |
+
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
|
91 |
+
*/
|
92 |
+
define('CRYPT_RIJNDAEL_MODE_ECB', 1);
|
93 |
+
/**
|
94 |
+
* Encrypt / decrypt using the Code Book Chaining mode.
|
95 |
+
*
|
96 |
+
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
|
97 |
+
*/
|
98 |
+
define('CRYPT_RIJNDAEL_MODE_CBC', 2);
|
99 |
+
/**
|
100 |
+
* Encrypt / decrypt using the Cipher Feedback mode.
|
101 |
+
*
|
102 |
+
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
|
103 |
+
*/
|
104 |
+
define('CRYPT_RIJNDAEL_MODE_CFB', 3);
|
105 |
+
/**
|
106 |
+
* Encrypt / decrypt using the Cipher Feedback mode.
|
107 |
+
*
|
108 |
+
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
|
109 |
+
*/
|
110 |
+
define('CRYPT_RIJNDAEL_MODE_OFB', 4);
|
111 |
+
/**#@-*/
|
112 |
+
|
113 |
+
/**#@+
|
114 |
+
* @access private
|
115 |
+
* @see Crypt_Rijndael::Crypt_Rijndael()
|
116 |
+
*/
|
117 |
+
/**
|
118 |
+
* Toggles the internal implementation
|
119 |
+
*/
|
120 |
+
define('CRYPT_RIJNDAEL_MODE_INTERNAL', 1);
|
121 |
+
/**
|
122 |
+
* Toggles the mcrypt implementation
|
123 |
+
*/
|
124 |
+
define('CRYPT_RIJNDAEL_MODE_MCRYPT', 2);
|
125 |
+
/**#@-*/
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Pure-PHP implementation of Rijndael.
|
129 |
+
*
|
130 |
+
* @author Jim Wigginton <terrafrost@php.net>
|
131 |
+
* @version 0.1.0
|
132 |
+
* @access public
|
133 |
+
* @package Crypt_Rijndael
|
134 |
+
*/
|
135 |
+
class Crypt_Rijndael {
|
136 |
+
/**
|
137 |
+
* The Encryption Mode
|
138 |
+
*
|
139 |
+
* @see Crypt_Rijndael::Crypt_Rijndael()
|
140 |
+
* @var Integer
|
141 |
+
* @access private
|
142 |
+
*/
|
143 |
+
var $mode;
|
144 |
+
|
145 |
+
/**
|
146 |
+
* The Key
|
147 |
+
*
|
148 |
+
* @see Crypt_Rijndael::setKey()
|
149 |
+
* @var String
|
150 |
+
* @access private
|
151 |
+
*/
|
152 |
+
var $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
153 |
+
|
154 |
+
/**
|
155 |
+
* The Initialization Vector
|
156 |
+
*
|
157 |
+
* @see Crypt_Rijndael::setIV()
|
158 |
+
* @var String
|
159 |
+
* @access private
|
160 |
+
*/
|
161 |
+
var $iv = '';
|
162 |
+
|
163 |
+
/**
|
164 |
+
* A "sliding" Initialization Vector
|
165 |
+
*
|
166 |
+
* @see Crypt_Rijndael::enableContinuousBuffer()
|
167 |
+
* @var String
|
168 |
+
* @access private
|
169 |
+
*/
|
170 |
+
var $encryptIV = '';
|
171 |
+
|
172 |
+
/**
|
173 |
+
* A "sliding" Initialization Vector
|
174 |
+
*
|
175 |
+
* @see Crypt_Rijndael::enableContinuousBuffer()
|
176 |
+
* @var String
|
177 |
+
* @access private
|
178 |
+
*/
|
179 |
+
var $decryptIV = '';
|
180 |
+
|
181 |
+
/**
|
182 |
+
* Continuous Buffer status
|
183 |
+
*
|
184 |
+
* @see Crypt_Rijndael::enableContinuousBuffer()
|
185 |
+
* @var Boolean
|
186 |
+
* @access private
|
187 |
+
*/
|
188 |
+
var $continuousBuffer = false;
|
189 |
+
|
190 |
+
/**
|
191 |
+
* Padding status
|
192 |
+
*
|
193 |
+
* @see Crypt_Rijndael::enablePadding()
|
194 |
+
* @var Boolean
|
195 |
+
* @access private
|
196 |
+
*/
|
197 |
+
var $padding = true;
|
198 |
+
|
199 |
+
/**
|
200 |
+
* Does the key schedule need to be (re)calculated?
|
201 |
+
*
|
202 |
+
* @see setKey()
|
203 |
+
* @see setBlockLength()
|
204 |
+
* @see setKeyLength()
|
205 |
+
* @var Boolean
|
206 |
+
* @access private
|
207 |
+
*/
|
208 |
+
var $changed = true;
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Has the key length explicitly been set or should it be derived from the key, itself?
|
212 |
+
*
|
213 |
+
* @see setKeyLength()
|
214 |
+
* @var Boolean
|
215 |
+
* @access private
|
216 |
+
*/
|
217 |
+
var $explicit_key_length = false;
|
218 |
+
|
219 |
+
/**
|
220 |
+
* The Key Schedule
|
221 |
+
*
|
222 |
+
* @see _setup()
|
223 |
+
* @var Array
|
224 |
+
* @access private
|
225 |
+
*/
|
226 |
+
var $w;
|
227 |
+
|
228 |
+
/**
|
229 |
+
* The Inverse Key Schedule
|
230 |
+
*
|
231 |
+
* @see _setup()
|
232 |
+
* @var Array
|
233 |
+
* @access private
|
234 |
+
*/
|
235 |
+
var $dw;
|
236 |
+
|
237 |
+
/**
|
238 |
+
* The Block Length
|
239 |
+
*
|
240 |
+
* @see setBlockLength()
|
241 |
+
* @var Integer
|
242 |
+
* @access private
|
243 |
+
* @internal The max value is 32, the min value is 16. All valid values are multiples of 4. Exists in conjunction with
|
244 |
+
* $Nb because we need this value and not $Nb to pad strings appropriately.
|
245 |
+
*/
|
246 |
+
var $block_size = 16;
|
247 |
+
|
248 |
+
/**
|
249 |
+
* The Block Length divided by 32
|
250 |
+
*
|
251 |
+
* @see setBlockLength()
|
252 |
+
* @var Integer
|
253 |
+
* @access private
|
254 |
+
* @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4. Exists in conjunction with $block_size
|
255 |
+
* because the encryption / decryption / key schedule creation requires this number and not $block_size. We could
|
256 |
+
* derive this from $block_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
|
257 |
+
* of that, we'll just precompute it once.
|
258 |
+
*
|
259 |
+
*/
|
260 |
+
var $Nb = 4;
|
261 |
+
|
262 |
+
/**
|
263 |
+
* The Key Length
|
264 |
+
*
|
265 |
+
* @see setKeyLength()
|
266 |
+
* @var Integer
|
267 |
+
* @access private
|
268 |
+
* @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $key_size
|
269 |
+
* because the encryption / decryption / key schedule creation requires this number and not $key_size. We could
|
270 |
+
* derive this from $key_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
|
271 |
+
* of that, we'll just precompute it once.
|
272 |
+
*/
|
273 |
+
var $key_size = 16;
|
274 |
+
|
275 |
+
/**
|
276 |
+
* The Key Length divided by 32
|
277 |
+
*
|
278 |
+
* @see setKeyLength()
|
279 |
+
* @var Integer
|
280 |
+
* @access private
|
281 |
+
* @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4
|
282 |
+
*/
|
283 |
+
var $Nk = 4;
|
284 |
+
|
285 |
+
/**
|
286 |
+
* The Number of Rounds
|
287 |
+
*
|
288 |
+
* @var Integer
|
289 |
+
* @access private
|
290 |
+
* @internal The max value is 14, the min value is 10.
|
291 |
+
*/
|
292 |
+
var $Nr;
|
293 |
+
|
294 |
+
/**
|
295 |
+
* Shift offsets
|
296 |
+
*
|
297 |
+
* @var Array
|
298 |
+
* @access private
|
299 |
+
*/
|
300 |
+
var $c;
|
301 |
+
|
302 |
+
/**
|
303 |
+
* Precomputed mixColumns table
|
304 |
+
*
|
305 |
+
* @see Crypt_Rijndael()
|
306 |
+
* @var Array
|
307 |
+
* @access private
|
308 |
+
*/
|
309 |
+
var $t0;
|
310 |
+
|
311 |
+
/**
|
312 |
+
* Precomputed mixColumns table
|
313 |
+
*
|
314 |
+
* @see Crypt_Rijndael()
|
315 |
+
* @var Array
|
316 |
+
* @access private
|
317 |
+
*/
|
318 |
+
var $t1;
|
319 |
+
|
320 |
+
/**
|
321 |
+
* Precomputed mixColumns table
|
322 |
+
*
|
323 |
+
* @see Crypt_Rijndael()
|
324 |
+
* @var Array
|
325 |
+
* @access private
|
326 |
+
*/
|
327 |
+
var $t2;
|
328 |
+
|
329 |
+
/**
|
330 |
+
* Precomputed mixColumns table
|
331 |
+
*
|
332 |
+
* @see Crypt_Rijndael()
|
333 |
+
* @var Array
|
334 |
+
* @access private
|
335 |
+
*/
|
336 |
+
var $t3;
|
337 |
+
|
338 |
+
/**
|
339 |
+
* Precomputed invMixColumns table
|
340 |
+
*
|
341 |
+
* @see Crypt_Rijndael()
|
342 |
+
* @var Array
|
343 |
+
* @access private
|
344 |
+
*/
|
345 |
+
var $dt0;
|
346 |
+
|
347 |
+
/**
|
348 |
+
* Precomputed invMixColumns table
|
349 |
+
*
|
350 |
+
* @see Crypt_Rijndael()
|
351 |
+
* @var Array
|
352 |
+
* @access private
|
353 |
+
*/
|
354 |
+
var $dt1;
|
355 |
+
|
356 |
+
/**
|
357 |
+
* Precomputed invMixColumns table
|
358 |
+
*
|
359 |
+
* @see Crypt_Rijndael()
|
360 |
+
* @var Array
|
361 |
+
* @access private
|
362 |
+
*/
|
363 |
+
var $dt2;
|
364 |
+
|
365 |
+
/**
|
366 |
+
* Precomputed invMixColumns table
|
367 |
+
*
|
368 |
+
* @see Crypt_Rijndael()
|
369 |
+
* @var Array
|
370 |
+
* @access private
|
371 |
+
*/
|
372 |
+
var $dt3;
|
373 |
+
|
374 |
+
/**
|
375 |
+
* Is the mode one that is paddable?
|
376 |
+
*
|
377 |
+
* @see Crypt_Rijndael::Crypt_Rijndael()
|
378 |
+
* @var Boolean
|
379 |
+
* @access private
|
380 |
+
*/
|
381 |
+
var $paddable = false;
|
382 |
+
|
383 |
+
/**
|
384 |
+
* Encryption buffer for CTR, OFB and CFB modes
|
385 |
+
*
|
386 |
+
* @see Crypt_Rijndael::encrypt()
|
387 |
+
* @var String
|
388 |
+
* @access private
|
389 |
+
*/
|
390 |
+
var $enbuffer = array('encrypted' => '', 'xor' => '');
|
391 |
+
|
392 |
+
/**
|
393 |
+
* Decryption buffer for CTR, OFB and CFB modes
|
394 |
+
*
|
395 |
+
* @see Crypt_Rijndael::decrypt()
|
396 |
+
* @var String
|
397 |
+
* @access private
|
398 |
+
*/
|
399 |
+
var $debuffer = array('ciphertext' => '');
|
400 |
+
|
401 |
+
/**
|
402 |
+
* Default Constructor.
|
403 |
+
*
|
404 |
+
* Determines whether or not the mcrypt extension should be used. $mode should only, at present, be
|
405 |
+
* CRYPT_RIJNDAEL_MODE_ECB or CRYPT_RIJNDAEL_MODE_CBC. If not explictly set, CRYPT_RIJNDAEL_MODE_CBC will be used.
|
406 |
+
*
|
407 |
+
* @param optional Integer $mode
|
408 |
+
* @return Crypt_Rijndael
|
409 |
+
* @access public
|
410 |
+
*/
|
411 |
+
function Crypt_Rijndael($mode = CRYPT_RIJNDAEL_MODE_CBC)
|
412 |
+
{
|
413 |
+
switch ($mode) {
|
414 |
+
case CRYPT_RIJNDAEL_MODE_ECB:
|
415 |
+
case CRYPT_RIJNDAEL_MODE_CBC:
|
416 |
+
$this->paddable = true;
|
417 |
+
$this->mode = $mode;
|
418 |
+
break;
|
419 |
+
case CRYPT_RIJNDAEL_MODE_CTR:
|
420 |
+
case CRYPT_RIJNDAEL_MODE_CFB:
|
421 |
+
case CRYPT_RIJNDAEL_MODE_OFB:
|
422 |
+
$this->mode = $mode;
|
423 |
+
break;
|
424 |
+
default:
|
425 |
+
$this->paddable = true;
|
426 |
+
$this->mode = CRYPT_RIJNDAEL_MODE_CBC;
|
427 |
+
}
|
428 |
+
|
429 |
+
$t3 = &$this->t3;
|
430 |
+
$t2 = &$this->t2;
|
431 |
+
$t1 = &$this->t1;
|
432 |
+
$t0 = &$this->t0;
|
433 |
+
|
434 |
+
$dt3 = &$this->dt3;
|
435 |
+
$dt2 = &$this->dt2;
|
436 |
+
$dt1 = &$this->dt1;
|
437 |
+
$dt0 = &$this->dt0;
|
438 |
+
|
439 |
+
// according to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=19> (section 5.2.1),
|
440 |
+
// precomputed tables can be used in the mixColumns phase. in that example, they're assigned t0...t3, so
|
441 |
+
// those are the names we'll use.
|
442 |
+
$t3 = array(
|
443 |
+
0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491,
|
444 |
+
0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC,
|
445 |
+
0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB,
|
446 |
+
0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B,
|
447 |
+
0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83,
|
448 |
+
0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A,
|
449 |
+
0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F,
|
450 |
+
0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA,
|
451 |
+
0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B,
|
452 |
+
0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713,
|
453 |
+
0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6,
|
454 |
+
0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85,
|
455 |
+
0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411,
|
456 |
+
0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B,
|
457 |
+
0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1,
|
458 |
+
0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF,
|
459 |
+
0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E,
|
460 |
+
0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6,
|
461 |
+
0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B,
|
462 |
+
0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD,
|
463 |
+
0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8,
|
464 |
+
0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2,
|
465 |
+
0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049,
|
466 |
+
0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810,
|
467 |
+
0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197,
|
468 |
+
0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F,
|
469 |
+
0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C,
|
470 |
+
0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927,
|
471 |
+
0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733,
|
472 |
+
0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5,
|
473 |
+
0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0,
|
474 |
+
0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C
|
475 |
+
);
|
476 |
+
|
477 |
+
$dt3 = array(
|
478 |
+
0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B,
|
479 |
+
0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5,
|
480 |
+
0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B,
|
481 |
+
0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, 0xE0692949, 0xC9C8448E,
|
482 |
+
0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D,
|
483 |
+
0xDF4A1863, 0x1A3182E5, 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9,
|
484 |
+
0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, 0x1F8F57E3, 0x55AB2A66,
|
485 |
+
0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED,
|
486 |
+
0xCF1C2B8A, 0x79B492A7, 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4,
|
487 |
+
0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, 0x719F065E, 0x6E1051BD,
|
488 |
+
0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60,
|
489 |
+
0x98FB2419, 0xBDE997D6, 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79,
|
490 |
+
0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, 0x1170AC1E, 0x5A724E6C,
|
491 |
+
0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24,
|
492 |
+
0x0A67B10C, 0x57E70F93, 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C,
|
493 |
+
0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, 0xB6A8B92D, 0x1EA9C814,
|
494 |
+
0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B,
|
495 |
+
0x4329768B, 0x23C6DCCB, 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084,
|
496 |
+
0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, 0x8652EC0D, 0xC1E3D077,
|
497 |
+
0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22,
|
498 |
+
0x494EC787, 0x38D1C1D9, 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F,
|
499 |
+
0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, 0x39F75E2E, 0xC3AFF582,
|
500 |
+
0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB,
|
501 |
+
0x267809CD, 0x5918F46E, 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF,
|
502 |
+
0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, 0xA59430C6, 0xA266C035,
|
503 |
+
0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17,
|
504 |
+
0x4DD68D76, 0xEFB04D43, 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46,
|
505 |
+
0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, 0x105633E9, 0xD647136D,
|
506 |
+
0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A,
|
507 |
+
0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678,
|
508 |
+
0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF,
|
509 |
+
0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0
|
510 |
+
);
|
511 |
+
|
512 |
+
for ($i = 0; $i < 256; $i++) {
|
513 |
+
$t2[$i << 8] = (($t3[$i] << 8) & 0xFFFFFF00) | (($t3[$i] >> 24) & 0x000000FF);
|
514 |
+
$t1[$i << 16] = (($t3[$i] << 16) & 0xFFFF0000) | (($t3[$i] >> 16) & 0x0000FFFF);
|
515 |
+
$t0[$i << 24] = (($t3[$i] << 24) & 0xFF000000) | (($t3[$i] >> 8) & 0x00FFFFFF);
|
516 |
+
|
517 |
+
$dt2[$i << 8] = (($this->dt3[$i] << 8) & 0xFFFFFF00) | (($dt3[$i] >> 24) & 0x000000FF);
|
518 |
+
$dt1[$i << 16] = (($this->dt3[$i] << 16) & 0xFFFF0000) | (($dt3[$i] >> 16) & 0x0000FFFF);
|
519 |
+
$dt0[$i << 24] = (($this->dt3[$i] << 24) & 0xFF000000) | (($dt3[$i] >> 8) & 0x00FFFFFF);
|
520 |
+
}
|
521 |
+
}
|
522 |
+
|
523 |
+
/**
|
524 |
+
* Sets the key.
|
525 |
+
*
|
526 |
+
* Keys can be of any length. Rijndael, itself, requires the use of a key that's between 128-bits and 256-bits long and
|
527 |
+
* whose length is a multiple of 32. If the key is less than 256-bits and the key length isn't set, we round the length
|
528 |
+
* up to the closest valid key length, padding $key with null bytes. If the key is more than 256-bits, we trim the
|
529 |
+
* excess bits.
|
530 |
+
*
|
531 |
+
* If the key is not explicitly set, it'll be assumed to be all null bytes.
|
532 |
+
*
|
533 |
+
* @access public
|
534 |
+
* @param String $key
|
535 |
+
*/
|
536 |
+
function setKey($key)
|
537 |
+
{
|
538 |
+
$this->key = $key;
|
539 |
+
$this->changed = true;
|
540 |
+
}
|
541 |
+
|
542 |
+
/**
|
543 |
+
* Sets the initialization vector. (optional)
|
544 |
+
*
|
545 |
+
* SetIV is not required when CRYPT_RIJNDAEL_MODE_ECB is being used. If not explictly set, it'll be assumed
|
546 |
+
* to be all zero's.
|
547 |
+
*
|
548 |
+
* @access public
|
549 |
+
* @param String $iv
|
550 |
+
*/
|
551 |
+
function setIV($iv)
|
552 |
+
{
|
553 |
+
$this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, $this->block_size), $this->block_size, chr(0));;
|
554 |
+
}
|
555 |
+
|
556 |
+
/**
|
557 |
+
* Sets the key length
|
558 |
+
*
|
559 |
+
* Valid key lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to
|
560 |
+
* 128. If the length is greater then 128 and invalid, it will be rounded down to the closest valid amount.
|
561 |
+
*
|
562 |
+
* @access public
|
563 |
+
* @param Integer $length
|
564 |
+
*/
|
565 |
+
function setKeyLength($length)
|
566 |
+
{
|
567 |
+
$length >>= 5;
|
568 |
+
if ($length > 8) {
|
569 |
+
$length = 8;
|
570 |
+
} else if ($length < 4) {
|
571 |
+
$length = 4;
|
572 |
+
}
|
573 |
+
$this->Nk = $length;
|
574 |
+
$this->key_size = $length << 2;
|
575 |
+
|
576 |
+
$this->explicit_key_length = true;
|
577 |
+
$this->changed = true;
|
578 |
+
}
|
579 |
+
|
580 |
+
/**
|
581 |
+
* Sets the block length
|
582 |
+
*
|
583 |
+
* Valid block lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to
|
584 |
+
* 128. If the length is greater then 128 and invalid, it will be rounded down to the closest valid amount.
|
585 |
+
*
|
586 |
+
* @access public
|
587 |
+
* @param Integer $length
|
588 |
+
*/
|
589 |
+
function setBlockLength($length)
|
590 |
+
{
|
591 |
+
$length >>= 5;
|
592 |
+
if ($length > 8) {
|
593 |
+
$length = 8;
|
594 |
+
} else if ($length < 4) {
|
595 |
+
$length = 4;
|
596 |
+
}
|
597 |
+
$this->Nb = $length;
|
598 |
+
$this->block_size = $length << 2;
|
599 |
+
$this->changed = true;
|
600 |
+
}
|
601 |
+
|
602 |
+
/**
|
603 |
+
* Generate CTR XOR encryption key
|
604 |
+
*
|
605 |
+
* Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
|
606 |
+
* plaintext / ciphertext in CTR mode.
|
607 |
+
*
|
608 |
+
* @see Crypt_Rijndael::decrypt()
|
609 |
+
* @see Crypt_Rijndael::encrypt()
|
610 |
+
* @access public
|
611 |
+
* @param Integer $length
|
612 |
+
* @param String $iv
|
613 |
+
*/
|
614 |
+
function _generate_xor($length, &$iv)
|
615 |
+
{
|
616 |
+
$xor = '';
|
617 |
+
$block_size = $this->block_size;
|
618 |
+
$num_blocks = floor(($length + ($block_size - 1)) / $block_size);
|
619 |
+
for ($i = 0; $i < $num_blocks; $i++) {
|
620 |
+
$xor.= $iv;
|
621 |
+
for ($j = 4; $j <= $block_size; $j+=4) {
|
622 |
+
$temp = substr($iv, -$j, 4);
|
623 |
+
switch ($temp) {
|
624 |
+
case "\xFF\xFF\xFF\xFF":
|
625 |
+
$iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
|
626 |
+
break;
|
627 |
+
case "\x7F\xFF\xFF\xFF":
|
628 |
+
$iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
|
629 |
+
break 2;
|
630 |
+
default:
|
631 |
+
extract(unpack('Ncount', $temp));
|
632 |
+
$iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
|
633 |
+
break 2;
|
634 |
+
}
|
635 |
+
}
|
636 |
+
}
|
637 |
+
|
638 |
+
return $xor;
|
639 |
+
}
|
640 |
+
|
641 |
+
/**
|
642 |
+
* Encrypts a message.
|
643 |
+
*
|
644 |
+
* $plaintext will be padded with additional bytes such that it's length is a multiple of the block size. Other Rjindael
|
645 |
+
* implementations may or may not pad in the same manner. Other common approaches to padding and the reasons why it's
|
646 |
+
* necessary are discussed in the following
|
647 |
+
* URL:
|
648 |
+
*
|
649 |
+
* {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
|
650 |
+
*
|
651 |
+
* An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
|
652 |
+
* strlen($plaintext) will still need to be a multiple of 8, however, arbitrary values can be added to make it that
|
653 |
+
* length.
|
654 |
+
*
|
655 |
+
* @see Crypt_Rijndael::decrypt()
|
656 |
+
* @access public
|
657 |
+
* @param String $plaintext
|
658 |
+
*/
|
659 |
+
function encrypt($plaintext)
|
660 |
+
{
|
661 |
+
$this->_setup();
|
662 |
+
if ($this->paddable) {
|
663 |
+
$plaintext = $this->_pad($plaintext);
|
664 |
+
}
|
665 |
+
|
666 |
+
$block_size = $this->block_size;
|
667 |
+
$buffer = &$this->enbuffer;
|
668 |
+
$continuousBuffer = $this->continuousBuffer;
|
669 |
+
$ciphertext = '';
|
670 |
+
switch ($this->mode) {
|
671 |
+
case CRYPT_RIJNDAEL_MODE_ECB:
|
672 |
+
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
673 |
+
$ciphertext.= $this->_encryptBlock(substr($plaintext, $i, $block_size));
|
674 |
+
}
|
675 |
+
break;
|
676 |
+
case CRYPT_RIJNDAEL_MODE_CBC:
|
677 |
+
$xor = $this->encryptIV;
|
678 |
+
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
679 |
+
$block = substr($plaintext, $i, $block_size);
|
680 |
+
$block = $this->_encryptBlock($block ^ $xor);
|
681 |
+
$xor = $block;
|
682 |
+
$ciphertext.= $block;
|
683 |
+
}
|
684 |
+
if ($this->continuousBuffer) {
|
685 |
+
$this->encryptIV = $xor;
|
686 |
+
}
|
687 |
+
break;
|
688 |
+
case CRYPT_RIJNDAEL_MODE_CTR:
|
689 |
+
$xor = $this->encryptIV;
|
690 |
+
if (!empty($buffer)) {
|
691 |
+
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
692 |
+
$block = substr($plaintext, $i, $block_size);
|
693 |
+
$buffer.= $this->_encryptBlock($this->_generate_xor($block_size, $xor));
|
694 |
+
$key = $this->_string_shift($buffer, $block_size);
|
695 |
+
$ciphertext.= $block ^ $key;
|
696 |
+
}
|
697 |
+
} else {
|
698 |
+
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
699 |
+
$block = substr($plaintext, $i, $block_size);
|
700 |
+
$key = $this->_encryptBlock($this->_generate_xor($block_size, $xor));
|
701 |
+
$ciphertext.= $block ^ $key;
|
702 |
+
}
|
703 |
+
}
|
704 |
+
if ($this->continuousBuffer) {
|
705 |
+
$this->encryptIV = $xor;
|
706 |
+
if ($start = strlen($plaintext) % $block_size) {
|
707 |
+
$buffer = substr($key, $start) . $buffer;
|
708 |
+
}
|
709 |
+
}
|
710 |
+
break;
|
711 |
+
case CRYPT_RIJNDAEL_MODE_CFB:
|
712 |
+
if (!empty($buffer['xor'])) {
|
713 |
+
$ciphertext = $plaintext ^ $buffer['xor'];
|
714 |
+
$iv = $buffer['encrypted'] . $ciphertext;
|
715 |
+
$start = strlen($ciphertext);
|
716 |
+
$buffer['encrypted'].= $ciphertext;
|
717 |
+
$buffer['xor'] = substr($buffer['xor'], strlen($ciphertext));
|
718 |
+
} else {
|
719 |
+
$ciphertext = '';
|
720 |
+
$iv = $this->encryptIV;
|
721 |
+
$start = 0;
|
722 |
+
}
|
723 |
+
|
724 |
+
for ($i = $start; $i < strlen($plaintext); $i+=$block_size) {
|
725 |
+
$block = substr($plaintext, $i, $block_size);
|
726 |
+
$xor = $this->_encryptBlock($iv);
|
727 |
+
$iv = $block ^ $xor;
|
728 |
+
if ($continuousBuffer && strlen($iv) != $block_size) {
|
729 |
+
$buffer = array(
|
730 |
+
'encrypted' => $iv,
|
731 |
+
'xor' => substr($xor, strlen($iv))
|
732 |
+
);
|
733 |
+
}
|
734 |
+
$ciphertext.= $iv;
|
735 |
+
}
|
736 |
+
|
737 |
+
if ($this->continuousBuffer) {
|
738 |
+
$this->encryptIV = $iv;
|
739 |
+
}
|
740 |
+
break;
|
741 |
+
case CRYPT_RIJNDAEL_MODE_OFB:
|
742 |
+
$xor = $this->encryptIV;
|
743 |
+
if (strlen($buffer)) {
|
744 |
+
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
745 |
+
$xor = $this->_encryptBlock($xor);
|
746 |
+
$buffer.= $xor;
|
747 |
+
$key = $this->_string_shift($buffer, $block_size);
|
748 |
+
$ciphertext.= substr($plaintext, $i, $block_size) ^ $key;
|
749 |
+
}
|
750 |
+
} else {
|
751 |
+
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
752 |
+
$xor = $this->_encryptBlock($xor);
|
753 |
+
$ciphertext.= substr($plaintext, $i, $block_size) ^ $xor;
|
754 |
+
}
|
755 |
+
$key = $xor;
|
756 |
+
}
|
757 |
+
if ($this->continuousBuffer) {
|
758 |
+
$this->encryptIV = $xor;
|
759 |
+
if ($start = strlen($plaintext) % $block_size) {
|
760 |
+
$buffer = substr($key, $start) . $buffer;
|
761 |
+
}
|
762 |
+
}
|
763 |
+
}
|
764 |
+
|
765 |
+
return $ciphertext;
|
766 |
+
}
|
767 |
+
|
768 |
+
/**
|
769 |
+
* Decrypts a message.
|
770 |
+
*
|
771 |
+
* If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until
|
772 |
+
* it is.
|
773 |
+
*
|
774 |
+
* @see Crypt_Rijndael::encrypt()
|
775 |
+
* @access public
|
776 |
+
* @param String $ciphertext
|
777 |
+
*/
|
778 |
+
function decrypt($ciphertext)
|
779 |
+
{
|
780 |
+
$this->_setup();
|
781 |
+
|
782 |
+
if ($this->paddable) {
|
783 |
+
// we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
|
784 |
+
// "The data is padded with "\0" to make sure the length of the data is n * blocksize."
|
785 |
+
$ciphertext = str_pad($ciphertext, strlen($ciphertext) + ($this->block_size - strlen($ciphertext) % $this->block_size) % $this->block_size, chr(0));
|
786 |
+
}
|
787 |
+
|
788 |
+
$block_size = $this->block_size;
|
789 |
+
$buffer = &$this->debuffer;
|
790 |
+
$continuousBuffer = $this->continuousBuffer;
|
791 |
+
$plaintext = '';
|
792 |
+
switch ($this->mode) {
|
793 |
+
case CRYPT_RIJNDAEL_MODE_ECB:
|
794 |
+
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
795 |
+
$plaintext.= $this->_decryptBlock(substr($ciphertext, $i, $block_size));
|
796 |
+
}
|
797 |
+
break;
|
798 |
+
case CRYPT_RIJNDAEL_MODE_CBC:
|
799 |
+
$xor = $this->decryptIV;
|
800 |
+
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
801 |
+
$block = substr($ciphertext, $i, $block_size);
|
802 |
+
$plaintext.= $this->_decryptBlock($block) ^ $xor;
|
803 |
+
$xor = $block;
|
804 |
+
}
|
805 |
+
if ($this->continuousBuffer) {
|
806 |
+
$this->decryptIV = $xor;
|
807 |
+
}
|
808 |
+
break;
|
809 |
+
case CRYPT_RIJNDAEL_MODE_CTR:
|
810 |
+
$xor = $this->decryptIV;
|
811 |
+
if (strlen($buffer)) {
|
812 |
+
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
813 |
+
$block = substr($ciphertext, $i, $block_size);
|
814 |
+
$buffer.= $this->_encryptBlock($this->_generate_xor($block_size, $xor));
|
815 |
+
$key = $this->_string_shift($buffer, $block_size);
|
816 |
+
$plaintext.= $block ^ $key;
|
817 |
+
}
|
818 |
+
} else {
|
819 |
+
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
820 |
+
$block = substr($ciphertext, $i, $block_size);
|
821 |
+
$key = $this->_encryptBlock($this->_generate_xor($block_size, $xor));
|
822 |
+
$plaintext.= $block ^ $key;
|
823 |
+
}
|
824 |
+
}
|
825 |
+
if ($this->continuousBuffer) {
|
826 |
+
$this->decryptIV = $xor;
|
827 |
+
if ($start = strlen($ciphertext) % $block_size) {
|
828 |
+
$buffer = substr($key, $start) . $buffer;
|
829 |
+
}
|
830 |
+
}
|
831 |
+
break;
|
832 |
+
case CRYPT_RIJNDAEL_MODE_CFB:
|
833 |
+
if (!empty($buffer['ciphertext'])) {
|
834 |
+
$plaintext = $ciphertext ^ substr($this->decryptIV, strlen($buffer['ciphertext']));
|
835 |
+
$buffer['ciphertext'].= substr($ciphertext, 0, strlen($plaintext));
|
836 |
+
if (strlen($buffer['ciphertext']) == $block_size) {
|
837 |
+
$xor = $this->_encryptBlock($buffer['ciphertext']);
|
838 |
+
$buffer['ciphertext'] = '';
|
839 |
+
}
|
840 |
+
$start = strlen($plaintext);
|
841 |
+
$block = $this->decryptIV;
|
842 |
+
} else {
|
843 |
+
$plaintext = '';
|
844 |
+
$xor = $this->_encryptBlock($this->decryptIV);
|
845 |
+
$start = 0;
|
846 |
+
}
|
847 |
+
|
848 |
+
for ($i = $start; $i < strlen($ciphertext); $i+=$block_size) {
|
849 |
+
$block = substr($ciphertext, $i, $block_size);
|
850 |
+
$plaintext.= $block ^ $xor;
|
851 |
+
if ($continuousBuffer && strlen($block) != $block_size) {
|
852 |
+
$buffer['ciphertext'].= $block;
|
853 |
+
$block = $xor;
|
854 |
+
} else if (strlen($block) == $block_size) {
|
855 |
+
$xor = $this->_encryptBlock($block);
|
856 |
+
}
|
857 |
+
}
|
858 |
+
if ($this->continuousBuffer) {
|
859 |
+
$this->decryptIV = $block;
|
860 |
+
}
|
861 |
+
break;
|
862 |
+
case CRYPT_RIJNDAEL_MODE_OFB:
|
863 |
+
$xor = $this->decryptIV;
|
864 |
+
if (strlen($buffer)) {
|
865 |
+
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
866 |
+
$xor = $this->_encryptBlock($xor);
|
867 |
+
$buffer.= $xor;
|
868 |
+
$key = $this->_string_shift($buffer, $block_size);
|
869 |
+
$plaintext.= substr($ciphertext, $i, $block_size) ^ $key;
|
870 |
+
}
|
871 |
+
} else {
|
872 |
+
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
873 |
+
$xor = $this->_encryptBlock($xor);
|
874 |
+
$plaintext.= substr($ciphertext, $i, $block_size) ^ $xor;
|
875 |
+
}
|
876 |
+
$key = $xor;
|
877 |
+
}
|
878 |
+
if ($this->continuousBuffer) {
|
879 |
+
$this->decryptIV = $xor;
|
880 |
+
if ($start = strlen($ciphertext) % $block_size) {
|
881 |
+
$buffer = substr($key, $start) . $buffer;
|
882 |
+
}
|
883 |
+
}
|
884 |
+
}
|
885 |
+
|
886 |
+
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
887 |
+
}
|
888 |
+
|
889 |
+
/**
|
890 |
+
* Encrypts a block
|
891 |
+
*
|
892 |
+
* @access private
|
893 |
+
* @param String $in
|
894 |
+
* @return String
|
895 |
+
*/
|
896 |
+
function _encryptBlock($in)
|
897 |
+
{
|
898 |
+
$state = array();
|
899 |
+
$words = unpack('N*word', $in);
|
900 |
+
|
901 |
+
$w = $this->w;
|
902 |
+
$t0 = $this->t0;
|
903 |
+
$t1 = $this->t1;
|
904 |
+
$t2 = $this->t2;
|
905 |
+
$t3 = $this->t3;
|
906 |
+
$Nb = $this->Nb;
|
907 |
+
$Nr = $this->Nr;
|
908 |
+
$c = $this->c;
|
909 |
+
|
910 |
+
// addRoundKey
|
911 |
+
$i = 0;
|
912 |
+
foreach ($words as $word) {
|
913 |
+
$state[] = $word ^ $w[0][$i++];
|
914 |
+
}
|
915 |
+
|
916 |
+
// fips-197.pdf#page=19, "Figure 5. Pseudo Code for the Cipher", states that this loop has four components -
|
917 |
+
// subBytes, shiftRows, mixColumns, and addRoundKey. fips-197.pdf#page=30, "Implementation Suggestions Regarding
|
918 |
+
// Various Platforms" suggests that performs enhanced implementations are described in Rijndael-ammended.pdf.
|
919 |
+
// Rijndael-ammended.pdf#page=20, "Implementation aspects / 32-bit processor", discusses such an optimization.
|
920 |
+
// Unfortunately, the description given there is not quite correct. Per aes.spec.v316.pdf#page=19 [1],
|
921 |
+
// equation (7.4.7) is supposed to use addition instead of subtraction, so we'll do that here, as well.
|
922 |
+
|
923 |
+
// [1] http://fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.v316.pdf
|
924 |
+
$temp = array();
|
925 |
+
for ($round = 1; $round < $Nr; $round++) {
|
926 |
+
$i = 0; // $c[0] == 0
|
927 |
+
$j = $c[1];
|
928 |
+
$k = $c[2];
|
929 |
+
$l = $c[3];
|
930 |
+
|
931 |
+
while ($i < $this->Nb) {
|
932 |
+
$temp[$i] = $t0[$state[$i] & 0xFF000000] ^
|
933 |
+
$t1[$state[$j] & 0x00FF0000] ^
|
934 |
+
$t2[$state[$k] & 0x0000FF00] ^
|
935 |
+
$t3[$state[$l] & 0x000000FF] ^
|
936 |
+
$w[$round][$i];
|
937 |
+
$i++;
|
938 |
+
$j = ($j + 1) % $Nb;
|
939 |
+
$k = ($k + 1) % $Nb;
|
940 |
+
$l = ($l + 1) % $Nb;
|
941 |
+
}
|
942 |
+
|
943 |
+
for ($i = 0; $i < $Nb; $i++) {
|
944 |
+
$state[$i] = $temp[$i];
|
945 |
+
}
|
946 |
+
}
|
947 |
+
|
948 |
+
// subWord
|
949 |
+
for ($i = 0; $i < $Nb; $i++) {
|
950 |
+
$state[$i] = $this->_subWord($state[$i]);
|
951 |
+
}
|
952 |
+
|
953 |
+
// shiftRows + addRoundKey
|
954 |
+
$i = 0; // $c[0] == 0
|
955 |
+
$j = $c[1];
|
956 |
+
$k = $c[2];
|
957 |
+
$l = $c[3];
|
958 |
+
while ($i < $this->Nb) {
|
959 |
+
$temp[$i] = ($state[$i] & 0xFF000000) ^
|
960 |
+
($state[$j] & 0x00FF0000) ^
|
961 |
+
($state[$k] & 0x0000FF00) ^
|
962 |
+
($state[$l] & 0x000000FF) ^
|
963 |
+
$w[$Nr][$i];
|
964 |
+
$i++;
|
965 |
+
$j = ($j + 1) % $Nb;
|
966 |
+
$k = ($k + 1) % $Nb;
|
967 |
+
$l = ($l + 1) % $Nb;
|
968 |
+
}
|
969 |
+
$state = $temp;
|
970 |
+
|
971 |
+
array_unshift($state, 'N*');
|
972 |
+
|
973 |
+
return call_user_func_array('pack', $state);
|
974 |
+
}
|
975 |
+
|
976 |
+
/**
|
977 |
+
* Decrypts a block
|
978 |
+
*
|
979 |
+
* @access private
|
980 |
+
* @param String $in
|
981 |
+
* @return String
|
982 |
+
*/
|
983 |
+
function _decryptBlock($in)
|
984 |
+
{
|
985 |
+
$state = array();
|
986 |
+
$words = unpack('N*word', $in);
|
987 |
+
|
988 |
+
$num_states = count($state);
|
989 |
+
$dw = $this->dw;
|
990 |
+
$dt0 = $this->dt0;
|
991 |
+
$dt1 = $this->dt1;
|
992 |
+
$dt2 = $this->dt2;
|
993 |
+
$dt3 = $this->dt3;
|
994 |
+
$Nb = $this->Nb;
|
995 |
+
$Nr = $this->Nr;
|
996 |
+
$c = $this->c;
|
997 |
+
|
998 |
+
// addRoundKey
|
999 |
+
$i = 0;
|
1000 |
+
foreach ($words as $word) {
|
1001 |
+
$state[] = $word ^ $dw[$Nr][$i++];
|
1002 |
+
}
|
1003 |
+
|
1004 |
+
$temp = array();
|
1005 |
+
for ($round = $Nr - 1; $round > 0; $round--) {
|
1006 |
+
$i = 0; // $c[0] == 0
|
1007 |
+
$j = $Nb - $c[1];
|
1008 |
+
$k = $Nb - $c[2];
|
1009 |
+
$l = $Nb - $c[3];
|
1010 |
+
|
1011 |
+
while ($i < $Nb) {
|
1012 |
+
$temp[$i] = $dt0[$state[$i] & 0xFF000000] ^
|
1013 |
+
$dt1[$state[$j] & 0x00FF0000] ^
|
1014 |
+
$dt2[$state[$k] & 0x0000FF00] ^
|
1015 |
+
$dt3[$state[$l] & 0x000000FF] ^
|
1016 |
+
$dw[$round][$i];
|
1017 |
+
$i++;
|
1018 |
+
$j = ($j + 1) % $Nb;
|
1019 |
+
$k = ($k + 1) % $Nb;
|
1020 |
+
$l = ($l + 1) % $Nb;
|
1021 |
+
}
|
1022 |
+
|
1023 |
+
for ($i = 0; $i < $Nb; $i++) {
|
1024 |
+
$state[$i] = $temp[$i];
|
1025 |
+
}
|
1026 |
+
}
|
1027 |
+
|
1028 |
+
// invShiftRows + invSubWord + addRoundKey
|
1029 |
+
$i = 0; // $c[0] == 0
|
1030 |
+
$j = $Nb - $c[1];
|
1031 |
+
$k = $Nb - $c[2];
|
1032 |
+
$l = $Nb - $c[3];
|
1033 |
+
|
1034 |
+
while ($i < $Nb) {
|
1035 |
+
$temp[$i] = $dw[0][$i] ^
|
1036 |
+
$this->_invSubWord(($state[$i] & 0xFF000000) |
|
1037 |
+
($state[$j] & 0x00FF0000) |
|
1038 |
+
($state[$k] & 0x0000FF00) |
|
1039 |
+
($state[$l] & 0x000000FF));
|
1040 |
+
$i++;
|
1041 |
+
$j = ($j + 1) % $Nb;
|
1042 |
+
$k = ($k + 1) % $Nb;
|
1043 |
+
$l = ($l + 1) % $Nb;
|
1044 |
+
}
|
1045 |
+
|
1046 |
+
$state = $temp;
|
1047 |
+
|
1048 |
+
array_unshift($state, 'N*');
|
1049 |
+
|
1050 |
+
return call_user_func_array('pack', $state);
|
1051 |
+
}
|
1052 |
+
|
1053 |
+
/**
|
1054 |
+
* Setup Rijndael
|
1055 |
+
*
|
1056 |
+
* Validates all the variables and calculates $Nr - the number of rounds that need to be performed - and $w - the key
|
1057 |
+
* key schedule.
|
1058 |
+
*
|
1059 |
+
* @access private
|
1060 |
+
*/
|
1061 |
+
function _setup()
|
1062 |
+
{
|
1063 |
+
// Each number in $rcon is equal to the previous number multiplied by two in Rijndael's finite field.
|
1064 |
+
// See http://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplicative_inverse
|
1065 |
+
static $rcon = array(0,
|
1066 |
+
0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
|
1067 |
+
0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000,
|
1068 |
+
0x6C000000, 0xD8000000, 0xAB000000, 0x4D000000, 0x9A000000,
|
1069 |
+
0x2F000000, 0x5E000000, 0xBC000000, 0x63000000, 0xC6000000,
|
1070 |
+
0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000,
|
1071 |
+
0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000
|
1072 |
+
);
|
1073 |
+
|
1074 |
+
if (!$this->changed) {
|
1075 |
+
return;
|
1076 |
+
}
|
1077 |
+
|
1078 |
+
if (!$this->explicit_key_length) {
|
1079 |
+
// we do >> 2, here, and not >> 5, as we do above, since strlen($this->key) tells us the number of bytes - not bits
|
1080 |
+
$length = strlen($this->key) >> 2;
|
1081 |
+
if ($length > 8) {
|
1082 |
+
$length = 8;
|
1083 |
+
} else if ($length < 4) {
|
1084 |
+
$length = 4;
|
1085 |
+
}
|
1086 |
+
$this->Nk = $length;
|
1087 |
+
$this->key_size = $length << 2;
|
1088 |
+
}
|
1089 |
+
|
1090 |
+
$this->key = str_pad(substr($this->key, 0, $this->key_size), $this->key_size, chr(0));
|
1091 |
+
$this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($this->iv, 0, $this->block_size), $this->block_size, chr(0));
|
1092 |
+
|
1093 |
+
// see Rijndael-ammended.pdf#page=44
|
1094 |
+
$this->Nr = max($this->Nk, $this->Nb) + 6;
|
1095 |
+
|
1096 |
+
// shift offsets for Nb = 5, 7 are defined in Rijndael-ammended.pdf#page=44,
|
1097 |
+
// "Table 8: Shift offsets in Shiftrow for the alternative block lengths"
|
1098 |
+
// shift offsets for Nb = 4, 6, 8 are defined in Rijndael-ammended.pdf#page=14,
|
1099 |
+
// "Table 2: Shift offsets for different block lengths"
|
1100 |
+
switch ($this->Nb) {
|
1101 |
+
case 4:
|
1102 |
+
case 5:
|
1103 |
+
case 6:
|
1104 |
+
$this->c = array(0, 1, 2, 3);
|
1105 |
+
break;
|
1106 |
+
case 7:
|
1107 |
+
$this->c = array(0, 1, 2, 4);
|
1108 |
+
break;
|
1109 |
+
case 8:
|
1110 |
+
$this->c = array(0, 1, 3, 4);
|
1111 |
+
}
|
1112 |
+
|
1113 |
+
$key = $this->key;
|
1114 |
+
|
1115 |
+
$w = array_values(unpack('N*words', $key));
|
1116 |
+
|
1117 |
+
$length = $this->Nb * ($this->Nr + 1);
|
1118 |
+
for ($i = $this->Nk; $i < $length; $i++) {
|
1119 |
+
$temp = $w[$i - 1];
|
1120 |
+
if ($i % $this->Nk == 0) {
|
1121 |
+
// according to <http://php.net/language.types.integer>, "the size of an integer is platform-dependent".
|
1122 |
+
// on a 32-bit machine, it's 32-bits, and on a 64-bit machine, it's 64-bits. on a 32-bit machine,
|
1123 |
+
// 0xFFFFFFFF << 8 == 0xFFFFFF00, but on a 64-bit machine, it equals 0xFFFFFFFF00. as such, doing 'and'
|
1124 |
+
// with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is.
|
1125 |
+
$temp = (($temp << 8) & 0xFFFFFF00) | (($temp >> 24) & 0x000000FF); // rotWord
|
1126 |
+
$temp = $this->_subWord($temp) ^ $rcon[$i / $this->Nk];
|
1127 |
+
} else if ($this->Nk > 6 && $i % $this->Nk == 4) {
|
1128 |
+
$temp = $this->_subWord($temp);
|
1129 |
+
}
|
1130 |
+
$w[$i] = $w[$i - $this->Nk] ^ $temp;
|
1131 |
+
}
|
1132 |
+
|
1133 |
+
// convert the key schedule from a vector of $Nb * ($Nr + 1) length to a matrix with $Nr + 1 rows and $Nb columns
|
1134 |
+
// and generate the inverse key schedule. more specifically,
|
1135 |
+
// according to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=23> (section 5.3.3),
|
1136 |
+
// "The key expansion for the Inverse Cipher is defined as follows:
|
1137 |
+
// 1. Apply the Key Expansion.
|
1138 |
+
// 2. Apply InvMixColumn to all Round Keys except the first and the last one."
|
1139 |
+
// also, see fips-197.pdf#page=27, "5.3.5 Equivalent Inverse Cipher"
|
1140 |
+
$temp = array();
|
1141 |
+
for ($i = $row = $col = 0; $i < $length; $i++, $col++) {
|
1142 |
+
if ($col == $this->Nb) {
|
1143 |
+
if ($row == 0) {
|
1144 |
+
$this->dw[0] = $this->w[0];
|
1145 |
+
} else {
|
1146 |
+
// subWord + invMixColumn + invSubWord = invMixColumn
|
1147 |
+
$j = 0;
|
1148 |
+
while ($j < $this->Nb) {
|
1149 |
+
$dw = $this->_subWord($this->w[$row][$j]);
|
1150 |
+
$temp[$j] = $this->dt0[$dw & 0xFF000000] ^
|
1151 |
+
$this->dt1[$dw & 0x00FF0000] ^
|
1152 |
+
$this->dt2[$dw & 0x0000FF00] ^
|
1153 |
+
$this->dt3[$dw & 0x000000FF];
|
1154 |
+
$j++;
|
1155 |
+
}
|
1156 |
+
$this->dw[$row] = $temp;
|
1157 |
+
}
|
1158 |
+
|
1159 |
+
$col = 0;
|
1160 |
+
$row++;
|
1161 |
+
}
|
1162 |
+
$this->w[$row][$col] = $w[$i];
|
1163 |
+
}
|
1164 |
+
|
1165 |
+
$this->dw[$row] = $this->w[$row];
|
1166 |
+
|
1167 |
+
$this->changed = false;
|
1168 |
+
}
|
1169 |
+
|
1170 |
+
/**
|
1171 |
+
* Performs S-Box substitutions
|
1172 |
+
*
|
1173 |
+
* @access private
|
1174 |
+
*/
|
1175 |
+
function _subWord($word)
|
1176 |
+
{
|
1177 |
+
static $sbox0, $sbox1, $sbox2, $sbox3;
|
1178 |
+
|
1179 |
+
if (empty($sbox0)) {
|
1180 |
+
$sbox0 = array(
|
1181 |
+
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
|
1182 |
+
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
|
1183 |
+
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
|
1184 |
+
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
|
1185 |
+
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
|
1186 |
+
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
|
1187 |
+
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
|
1188 |
+
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
|
1189 |
+
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
|
1190 |
+
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
|
1191 |
+
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
|
1192 |
+
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
|
1193 |
+
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
|
1194 |
+
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
|
1195 |
+
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
|
1196 |
+
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
|
1197 |
+
);
|
1198 |
+
|
1199 |
+
$sbox1 = array();
|
1200 |
+
$sbox2 = array();
|
1201 |
+
$sbox3 = array();
|
1202 |
+
|
1203 |
+
for ($i = 0; $i < 256; $i++) {
|
1204 |
+
$sbox1[$i << 8] = $sbox0[$i] << 8;
|
1205 |
+
$sbox2[$i << 16] = $sbox0[$i] << 16;
|
1206 |
+
$sbox3[$i << 24] = $sbox0[$i] << 24;
|
1207 |
+
}
|
1208 |
+
}
|
1209 |
+
|
1210 |
+
return $sbox0[$word & 0x000000FF] |
|
1211 |
+
$sbox1[$word & 0x0000FF00] |
|
1212 |
+
$sbox2[$word & 0x00FF0000] |
|
1213 |
+
$sbox3[$word & 0xFF000000];
|
1214 |
+
}
|
1215 |
+
|
1216 |
+
/**
|
1217 |
+
* Performs inverse S-Box substitutions
|
1218 |
+
*
|
1219 |
+
* @access private
|
1220 |
+
*/
|
1221 |
+
function _invSubWord($word)
|
1222 |
+
{
|
1223 |
+
static $sbox0, $sbox1, $sbox2, $sbox3;
|
1224 |
+
|
1225 |
+
if (empty($sbox0)) {
|
1226 |
+
$sbox0 = array(
|
1227 |
+
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
|
1228 |
+
0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
|
1229 |
+
0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
|
1230 |
+
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
|
1231 |
+
0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
|
1232 |
+
0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
|
1233 |
+
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
|
1234 |
+
0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
|
1235 |
+
0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
|
1236 |
+
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
|
1237 |
+
0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
|
1238 |
+
0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
|
1239 |
+
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
|
1240 |
+
0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
|
1241 |
+
0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
|
1242 |
+
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
|
1243 |
+
);
|
1244 |
+
|
1245 |
+
$sbox1 = array();
|
1246 |
+
$sbox2 = array();
|
1247 |
+
$sbox3 = array();
|
1248 |
+
|
1249 |
+
for ($i = 0; $i < 256; $i++) {
|
1250 |
+
$sbox1[$i << 8] = $sbox0[$i] << 8;
|
1251 |
+
$sbox2[$i << 16] = $sbox0[$i] << 16;
|
1252 |
+
$sbox3[$i << 24] = $sbox0[$i] << 24;
|
1253 |
+
}
|
1254 |
+
}
|
1255 |
+
|
1256 |
+
return $sbox0[$word & 0x000000FF] |
|
1257 |
+
$sbox1[$word & 0x0000FF00] |
|
1258 |
+
$sbox2[$word & 0x00FF0000] |
|
1259 |
+
$sbox3[$word & 0xFF000000];
|
1260 |
+
}
|
1261 |
+
|
1262 |
+
/**
|
1263 |
+
* Pad "packets".
|
1264 |
+
*
|
1265 |
+
* Rijndael works by encrypting between sixteen and thirty-two bytes at a time, provided that number is also a multiple
|
1266 |
+
* of four. If you ever need to encrypt or decrypt something that isn't of the proper length, it becomes necessary to
|
1267 |
+
* pad the input so that it is of the proper length.
|
1268 |
+
*
|
1269 |
+
* Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH,
|
1270 |
+
* where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping
|
1271 |
+
* away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
|
1272 |
+
* transmitted separately)
|
1273 |
+
*
|
1274 |
+
* @see Crypt_Rijndael::disablePadding()
|
1275 |
+
* @access public
|
1276 |
+
*/
|
1277 |
+
function enablePadding()
|
1278 |
+
{
|
1279 |
+
$this->padding = true;
|
1280 |
+
}
|
1281 |
+
|
1282 |
+
/**
|
1283 |
+
* Do not pad packets.
|
1284 |
+
*
|
1285 |
+
* @see Crypt_Rijndael::enablePadding()
|
1286 |
+
* @access public
|
1287 |
+
*/
|
1288 |
+
function disablePadding()
|
1289 |
+
{
|
1290 |
+
$this->padding = false;
|
1291 |
+
}
|
1292 |
+
|
1293 |
+
/**
|
1294 |
+
* Pads a string
|
1295 |
+
*
|
1296 |
+
* Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize.
|
1297 |
+
* $block_size - (strlen($text) % $block_size) bytes are added, each of which is equal to
|
1298 |
+
* chr($block_size - (strlen($text) % $block_size)
|
1299 |
+
*
|
1300 |
+
* If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
|
1301 |
+
* and padding will, hence forth, be enabled.
|
1302 |
+
*
|
1303 |
+
* @see Crypt_Rijndael::_unpad()
|
1304 |
+
* @access private
|
1305 |
+
*/
|
1306 |
+
function _pad($text)
|
1307 |
+
{
|
1308 |
+
$length = strlen($text);
|
1309 |
+
|
1310 |
+
if (!$this->padding) {
|
1311 |
+
if ($length % $this->block_size == 0) {
|
1312 |
+
return $text;
|
1313 |
+
} else {
|
1314 |
+
user_error("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size})", E_USER_NOTICE);
|
1315 |
+
$this->padding = true;
|
1316 |
+
}
|
1317 |
+
}
|
1318 |
+
|
1319 |
+
$pad = $this->block_size - ($length % $this->block_size);
|
1320 |
+
|
1321 |
+
return str_pad($text, $length + $pad, chr($pad));
|
1322 |
+
}
|
1323 |
+
|
1324 |
+
/**
|
1325 |
+
* Unpads a string.
|
1326 |
+
*
|
1327 |
+
* If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
|
1328 |
+
* and false will be returned.
|
1329 |
+
*
|
1330 |
+
* @see Crypt_Rijndael::_pad()
|
1331 |
+
* @access private
|
1332 |
+
*/
|
1333 |
+
function _unpad($text)
|
1334 |
+
{
|
1335 |
+
if (!$this->padding) {
|
1336 |
+
return $text;
|
1337 |
+
}
|
1338 |
+
|
1339 |
+
$length = ord($text[strlen($text) - 1]);
|
1340 |
+
|
1341 |
+
if (!$length || $length > $this->block_size) {
|
1342 |
+
return false;
|
1343 |
+
}
|
1344 |
+
|
1345 |
+
return substr($text, 0, -$length);
|
1346 |
+
}
|
1347 |
+
|
1348 |
+
/**
|
1349 |
+
* Treat consecutive "packets" as if they are a continuous buffer.
|
1350 |
+
*
|
1351 |
+
* Say you have a 32-byte plaintext $plaintext. Using the default behavior, the two following code snippets
|
1352 |
+
* will yield different outputs:
|
1353 |
+
*
|
1354 |
+
* <code>
|
1355 |
+
* echo $rijndael->encrypt(substr($plaintext, 0, 16));
|
1356 |
+
* echo $rijndael->encrypt(substr($plaintext, 16, 16));
|
1357 |
+
* </code>
|
1358 |
+
* <code>
|
1359 |
+
* echo $rijndael->encrypt($plaintext);
|
1360 |
+
* </code>
|
1361 |
+
*
|
1362 |
+
* The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
|
1363 |
+
* another, as demonstrated with the following:
|
1364 |
+
*
|
1365 |
+
* <code>
|
1366 |
+
* $rijndael->encrypt(substr($plaintext, 0, 16));
|
1367 |
+
* echo $rijndael->decrypt($des->encrypt(substr($plaintext, 16, 16)));
|
1368 |
+
* </code>
|
1369 |
+
* <code>
|
1370 |
+
* echo $rijndael->decrypt($des->encrypt(substr($plaintext, 16, 16)));
|
1371 |
+
* </code>
|
1372 |
+
*
|
1373 |
+
* With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
|
1374 |
+
* outputs. The reason is due to the fact that the initialization vector's change after every encryption /
|
1375 |
+
* decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
|
1376 |
+
*
|
1377 |
+
* Put another way, when the continuous buffer is enabled, the state of the Crypt_Rijndael() object changes after each
|
1378 |
+
* encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
|
1379 |
+
* continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
|
1380 |
+
* however, they are also less intuitive and more likely to cause you problems.
|
1381 |
+
*
|
1382 |
+
* @see Crypt_Rijndael::disableContinuousBuffer()
|
1383 |
+
* @access public
|
1384 |
+
*/
|
1385 |
+
function enableContinuousBuffer()
|
1386 |
+
{
|
1387 |
+
$this->continuousBuffer = true;
|
1388 |
+
}
|
1389 |
+
|
1390 |
+
/**
|
1391 |
+
* Treat consecutive packets as if they are a discontinuous buffer.
|
1392 |
+
*
|
1393 |
+
* The default behavior.
|
1394 |
+
*
|
1395 |
+
* @see Crypt_Rijndael::enableContinuousBuffer()
|
1396 |
+
* @access public
|
1397 |
+
*/
|
1398 |
+
function disableContinuousBuffer()
|
1399 |
+
{
|
1400 |
+
$this->continuousBuffer = false;
|
1401 |
+
$this->encryptIV = $this->iv;
|
1402 |
+
$this->decryptIV = $this->iv;
|
1403 |
+
}
|
1404 |
+
|
1405 |
+
/**
|
1406 |
+
* String Shift
|
1407 |
+
*
|
1408 |
+
* Inspired by array_shift
|
1409 |
+
*
|
1410 |
+
* @param String $string
|
1411 |
+
* @param optional Integer $index
|
1412 |
+
* @return String
|
1413 |
+
* @access private
|
1414 |
+
*/
|
1415 |
+
function _string_shift(&$string, $index = 1)
|
1416 |
+
{
|
1417 |
+
$substr = substr($string, 0, $index);
|
1418 |
+
$string = substr($string, $index);
|
1419 |
+
return $substr;
|
1420 |
+
}
|
1421 |
+
}
|
1422 |
+
|
1423 |
+
// vim: ts=4:sw=4:et:
|
1424 |
+
// vim6: fdl=1:
|
trunk/includes/S3.php
ADDED
@@ -0,0 +1,2211 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* $Id$
|
4 |
+
*
|
5 |
+
* Copyright (c) 2011, Donovan Schönknecht. All rights reserved.
|
6 |
+
* Portions copyright (c) 2012, David Anderson (http://www.simbahosting.co.uk). All rights reserved.
|
7 |
+
*
|
8 |
+
* Redistribution and use in source and binary forms, with or without
|
9 |
+
* modification, are permitted provided that the following conditions are met:
|
10 |
+
*
|
11 |
+
* - Redistributions of source code must retain the above copyright notice,
|
12 |
+
* this list of conditions and the following disclaimer.
|
13 |
+
* - Redistributions in binary form must reproduce the above copyright
|
14 |
+
* notice, this list of conditions and the following disclaimer in the
|
15 |
+
* documentation and/or other materials provided with the distribution.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
18 |
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
19 |
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
20 |
+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
21 |
+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
22 |
+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
23 |
+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
24 |
+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
25 |
+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
26 |
+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27 |
+
* POSSIBILITY OF SUCH DAMAGE.
|
28 |
+
*
|
29 |
+
* Amazon S3 is a trademark of Amazon.com, Inc. or its affiliates.
|
30 |
+
*/
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Amazon S3 PHP class
|
34 |
+
*
|
35 |
+
* @link http://undesigned.org.za/2007/10/22/amazon-s3-php-class
|
36 |
+
* @version 0.5.0-dev
|
37 |
+
*/
|
38 |
+
class S3
|
39 |
+
{
|
40 |
+
// ACL flags
|
41 |
+
const ACL_PRIVATE = 'private';
|
42 |
+
const ACL_PUBLIC_READ = 'public-read';
|
43 |
+
const ACL_PUBLIC_READ_WRITE = 'public-read-write';
|
44 |
+
const ACL_AUTHENTICATED_READ = 'authenticated-read';
|
45 |
+
|
46 |
+
const STORAGE_CLASS_STANDARD = 'STANDARD';
|
47 |
+
const STORAGE_CLASS_RRS = 'REDUCED_REDUNDANCY';
|
48 |
+
|
49 |
+
private static $__accessKey = null; // AWS Access key
|
50 |
+
private static $__secretKey = null; // AWS Secret key
|
51 |
+
private static $__sslKey = null;
|
52 |
+
|
53 |
+
public static $endpoint = 's3.amazonaws.com';
|
54 |
+
public static $proxy = null;
|
55 |
+
|
56 |
+
public static $useSSL = false;
|
57 |
+
public static $useSSLValidation = true;
|
58 |
+
public static $useExceptions = false;
|
59 |
+
|
60 |
+
// SSL CURL SSL options - only needed if you are experiencing problems with your OpenSSL configuration
|
61 |
+
public static $sslKey = null;
|
62 |
+
public static $sslCert = null;
|
63 |
+
public static $sslCACert = null;
|
64 |
+
|
65 |
+
private static $__signingKeyPairId = null; // AWS Key Pair ID
|
66 |
+
private static $__signingKeyResource = false; // Key resource, freeSigningKey() must be called to clear it from memory
|
67 |
+
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Constructor - if you're not using the class statically
|
71 |
+
*
|
72 |
+
* @param string $accessKey Access key
|
73 |
+
* @param string $secretKey Secret key
|
74 |
+
* @param boolean $useSSL Enable SSL
|
75 |
+
* @return void
|
76 |
+
*/
|
77 |
+
public function __construct($accessKey = null, $secretKey = null, $useSSL = false, $endpoint = 's3.amazonaws.com')
|
78 |
+
{
|
79 |
+
if ($accessKey !== null && $secretKey !== null)
|
80 |
+
self::setAuth($accessKey, $secretKey);
|
81 |
+
self::$useSSL = $useSSL;
|
82 |
+
self::$endpoint = $endpoint;
|
83 |
+
}
|
84 |
+
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Set the sertvice endpoint
|
88 |
+
*
|
89 |
+
* @param string $host Hostname
|
90 |
+
* @return void
|
91 |
+
*/
|
92 |
+
public function setEndpoint($host)
|
93 |
+
{
|
94 |
+
self::$endpoint = $host;
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Set AWS access key and secret key
|
99 |
+
*
|
100 |
+
* @param string $accessKey Access key
|
101 |
+
* @param string $secretKey Secret key
|
102 |
+
* @return void
|
103 |
+
*/
|
104 |
+
public static function setAuth($accessKey, $secretKey)
|
105 |
+
{
|
106 |
+
self::$__accessKey = $accessKey;
|
107 |
+
self::$__secretKey = $secretKey;
|
108 |
+
}
|
109 |
+
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Check if AWS keys have been set
|
113 |
+
*
|
114 |
+
* @return boolean
|
115 |
+
*/
|
116 |
+
public static function hasAuth() {
|
117 |
+
return (self::$__accessKey !== null && self::$__secretKey !== null);
|
118 |
+
}
|
119 |
+
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Set SSL on or off
|
123 |
+
*
|
124 |
+
* @param boolean $enabled SSL enabled
|
125 |
+
* @param boolean $validate SSL certificate validation
|
126 |
+
* @return void
|
127 |
+
*/
|
128 |
+
public static function setSSL($enabled, $validate = true)
|
129 |
+
{
|
130 |
+
self::$useSSL = $enabled;
|
131 |
+
self::$useSSLValidation = $validate;
|
132 |
+
}
|
133 |
+
|
134 |
+
|
135 |
+
/**
|
136 |
+
* Set SSL client certificates (experimental)
|
137 |
+
*
|
138 |
+
* @param string $sslCert SSL client certificate
|
139 |
+
* @param string $sslKey SSL client key
|
140 |
+
* @param string $sslCACert SSL CA cert (only required if you are having problems with your system CA cert)
|
141 |
+
* @return void
|
142 |
+
*/
|
143 |
+
public static function setSSLAuth($sslCert = null, $sslKey = null, $sslCACert = null)
|
144 |
+
{
|
145 |
+
self::$sslCert = $sslCert;
|
146 |
+
self::$sslKey = $sslKey;
|
147 |
+
self::$sslCACert = $sslCACert;
|
148 |
+
}
|
149 |
+
|
150 |
+
|
151 |
+
/**
|
152 |
+
* Set proxy information
|
153 |
+
*
|
154 |
+
* @param string $host Proxy hostname and port (localhost:1234)
|
155 |
+
* @param string $user Proxy username
|
156 |
+
* @param string $pass Proxy password
|
157 |
+
* @param constant $type CURL proxy type
|
158 |
+
* @return void
|
159 |
+
*/
|
160 |
+
public static function setProxy($host, $user = null, $pass = null, $type = CURLPROXY_SOCKS5)
|
161 |
+
{
|
162 |
+
self::$proxy = array('host' => $host, 'type' => $type, 'user' => null, 'pass' => 'null');
|
163 |
+
}
|
164 |
+
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Set the error mode to exceptions
|
168 |
+
*
|
169 |
+
* @param boolean $enabled Enable exceptions
|
170 |
+
* @return void
|
171 |
+
*/
|
172 |
+
public static function setExceptions($enabled = true)
|
173 |
+
{
|
174 |
+
self::$useExceptions = $enabled;
|
175 |
+
}
|
176 |
+
|
177 |
+
|
178 |
+
/**
|
179 |
+
* Set signing key
|
180 |
+
*
|
181 |
+
* @param string $keyPairId AWS Key Pair ID
|
182 |
+
* @param string $signingKey Private Key
|
183 |
+
* @param boolean $isFile Load private key from file, set to false to load string
|
184 |
+
* @return boolean
|
185 |
+
*/
|
186 |
+
public static function setSigningKey($keyPairId, $signingKey, $isFile = true)
|
187 |
+
{
|
188 |
+
self::$__signingKeyPairId = $keyPairId;
|
189 |
+
if ((self::$__signingKeyResource = openssl_pkey_get_private($isFile ?
|
190 |
+
file_get_contents($signingKey) : $signingKey)) !== false) return true;
|
191 |
+
self::__triggerError('S3::setSigningKey(): Unable to open load private key: '.$signingKey, __FILE__, __LINE__);
|
192 |
+
return false;
|
193 |
+
}
|
194 |
+
|
195 |
+
|
196 |
+
/**
|
197 |
+
* Free signing key from memory, MUST be called if you are using setSigningKey()
|
198 |
+
*
|
199 |
+
* @return void
|
200 |
+
*/
|
201 |
+
public static function freeSigningKey()
|
202 |
+
{
|
203 |
+
if (self::$__signingKeyResource !== false)
|
204 |
+
openssl_free_key(self::$__signingKeyResource);
|
205 |
+
}
|
206 |
+
|
207 |
+
|
208 |
+
/**
|
209 |
+
* Internal error handler
|
210 |
+
*
|
211 |
+
* @internal Internal error handler
|
212 |
+
* @param string $message Error message
|
213 |
+
* @param string $file Filename
|
214 |
+
* @param integer $line Line number
|
215 |
+
* @param integer $code Error code
|
216 |
+
* @return void
|
217 |
+
*/
|
218 |
+
private static function __triggerError($message, $file, $line, $code = 0)
|
219 |
+
{
|
220 |
+
if (self::$useExceptions)
|
221 |
+
throw new S3Exception($message, $file, $line, $code);
|
222 |
+
else
|
223 |
+
trigger_error($message, E_USER_WARNING);
|
224 |
+
}
|
225 |
+
|
226 |
+
|
227 |
+
/**
|
228 |
+
* Get a list of buckets
|
229 |
+
*
|
230 |
+
* @param boolean $detailed Returns detailed bucket list when true
|
231 |
+
* @return array | false
|
232 |
+
*/
|
233 |
+
public static function listBuckets($detailed = false)
|
234 |
+
{
|
235 |
+
$rest = new S3Request('GET', '', '', self::$endpoint);
|
236 |
+
$rest = $rest->getResponse();
|
237 |
+
if ($rest->error === false && $rest->code !== 200)
|
238 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
239 |
+
if ($rest->error !== false)
|
240 |
+
{
|
241 |
+
self::__triggerError(sprintf("S3::listBuckets(): [%s] %s", $rest->error['code'],
|
242 |
+
$rest->error['message']), __FILE__, __LINE__);
|
243 |
+
return false;
|
244 |
+
}
|
245 |
+
$results = array();
|
246 |
+
if (!isset($rest->body->Buckets)) return $results;
|
247 |
+
|
248 |
+
if ($detailed)
|
249 |
+
{
|
250 |
+
if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName))
|
251 |
+
$results['owner'] = array(
|
252 |
+
'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->ID
|
253 |
+
);
|
254 |
+
$results['buckets'] = array();
|
255 |
+
foreach ($rest->body->Buckets->Bucket as $b)
|
256 |
+
$results['buckets'][] = array(
|
257 |
+
'name' => (string)$b->Name, 'time' => strtotime((string)$b->CreationDate)
|
258 |
+
);
|
259 |
+
} else
|
260 |
+
foreach ($rest->body->Buckets->Bucket as $b) $results[] = (string)$b->Name;
|
261 |
+
|
262 |
+
return $results;
|
263 |
+
}
|
264 |
+
|
265 |
+
|
266 |
+
/*
|
267 |
+
* Get contents for a bucket
|
268 |
+
*
|
269 |
+
* If maxKeys is null this method will loop through truncated result sets
|
270 |
+
*
|
271 |
+
* @param string $bucket Bucket name
|
272 |
+
* @param string $prefix Prefix
|
273 |
+
* @param string $marker Marker (last file listed)
|
274 |
+
* @param string $maxKeys Max keys (maximum number of keys to return)
|
275 |
+
* @param string $delimiter Delimiter
|
276 |
+
* @param boolean $returnCommonPrefixes Set to true to return CommonPrefixes
|
277 |
+
* @return array | false
|
278 |
+
*/
|
279 |
+
public static function getBucket($bucket, $prefix = null, $marker = null, $maxKeys = null, $delimiter = null, $returnCommonPrefixes = false)
|
280 |
+
{
|
281 |
+
$rest = new S3Request('GET', $bucket, '', self::$endpoint);
|
282 |
+
if ($maxKeys == 0) $maxKeys = null;
|
283 |
+
if ($prefix !== null && $prefix !== '') $rest->setParameter('prefix', $prefix);
|
284 |
+
if ($marker !== null && $marker !== '') $rest->setParameter('marker', $marker);
|
285 |
+
if ($maxKeys !== null && $maxKeys !== '') $rest->setParameter('max-keys', $maxKeys);
|
286 |
+
if ($delimiter !== null && $delimiter !== '') $rest->setParameter('delimiter', $delimiter);
|
287 |
+
$response = $rest->getResponse();
|
288 |
+
if ($response->error === false && $response->code !== 200)
|
289 |
+
$response->error = array('code' => $response->code, 'message' => 'Unexpected HTTP status');
|
290 |
+
if ($response->error !== false)
|
291 |
+
{
|
292 |
+
self::__triggerError(sprintf("S3::getBucket(): [%s] %s",
|
293 |
+
$response->error['code'], $response->error['message']), __FILE__, __LINE__);
|
294 |
+
return false;
|
295 |
+
}
|
296 |
+
|
297 |
+
$results = array();
|
298 |
+
|
299 |
+
$nextMarker = null;
|
300 |
+
if (isset($response->body, $response->body->Contents))
|
301 |
+
foreach ($response->body->Contents as $c)
|
302 |
+
{
|
303 |
+
$results[(string)$c->Key] = array(
|
304 |
+
'name' => (string)$c->Key,
|
305 |
+
'time' => strtotime((string)$c->LastModified),
|
306 |
+
'size' => (int)$c->Size,
|
307 |
+
'hash' => substr((string)$c->ETag, 1, -1)
|
308 |
+
);
|
309 |
+
$nextMarker = (string)$c->Key;
|
310 |
+
}
|
311 |
+
|
312 |
+
if ($returnCommonPrefixes && isset($response->body, $response->body->CommonPrefixes))
|
313 |
+
foreach ($response->body->CommonPrefixes as $c)
|
314 |
+
$results[(string)$c->Prefix] = array('prefix' => (string)$c->Prefix);
|
315 |
+
|
316 |
+
if (isset($response->body, $response->body->IsTruncated) &&
|
317 |
+
(string)$response->body->IsTruncated == 'false') return $results;
|
318 |
+
|
319 |
+
if (isset($response->body, $response->body->NextMarker))
|
320 |
+
$nextMarker = (string)$response->body->NextMarker;
|
321 |
+
|
322 |
+
// Loop through truncated results if maxKeys isn't specified
|
323 |
+
if ($maxKeys == null && $nextMarker !== null && (string)$response->body->IsTruncated == 'true')
|
324 |
+
do
|
325 |
+
{
|
326 |
+
$rest = new S3Request('GET', $bucket, '', self::$endpoint);
|
327 |
+
if ($prefix !== null && $prefix !== '') $rest->setParameter('prefix', $prefix);
|
328 |
+
$rest->setParameter('marker', $nextMarker);
|
329 |
+
if ($delimiter !== null && $delimiter !== '') $rest->setParameter('delimiter', $delimiter);
|
330 |
+
|
331 |
+
if (($response = $rest->getResponse()) == false || $response->code !== 200) break;
|
332 |
+
|
333 |
+
if (isset($response->body, $response->body->Contents))
|
334 |
+
foreach ($response->body->Contents as $c)
|
335 |
+
{
|
336 |
+
$results[(string)$c->Key] = array(
|
337 |
+
'name' => (string)$c->Key,
|
338 |
+
'time' => strtotime((string)$c->LastModified),
|
339 |
+
'size' => (int)$c->Size,
|
340 |
+
'hash' => substr((string)$c->ETag, 1, -1)
|
341 |
+
);
|
342 |
+
$nextMarker = (string)$c->Key;
|
343 |
+
}
|
344 |
+
|
345 |
+
if ($returnCommonPrefixes && isset($response->body, $response->body->CommonPrefixes))
|
346 |
+
foreach ($response->body->CommonPrefixes as $c)
|
347 |
+
$results[(string)$c->Prefix] = array('prefix' => (string)$c->Prefix);
|
348 |
+
|
349 |
+
if (isset($response->body, $response->body->NextMarker))
|
350 |
+
$nextMarker = (string)$response->body->NextMarker;
|
351 |
+
|
352 |
+
} while ($response !== false && (string)$response->body->IsTruncated == 'true');
|
353 |
+
|
354 |
+
return $results;
|
355 |
+
}
|
356 |
+
|
357 |
+
|
358 |
+
/**
|
359 |
+
* Put a bucket
|
360 |
+
*
|
361 |
+
* @param string $bucket Bucket name
|
362 |
+
* @param constant $acl ACL flag
|
363 |
+
* @param string $location Set as "EU" to create buckets hosted in Europe
|
364 |
+
* @return boolean
|
365 |
+
*/
|
366 |
+
public static function putBucket($bucket, $acl = self::ACL_PRIVATE, $location = false)
|
367 |
+
{
|
368 |
+
$rest = new S3Request('PUT', $bucket, '', self::$endpoint);
|
369 |
+
$rest->setAmzHeader('x-amz-acl', $acl);
|
370 |
+
|
371 |
+
if ($location !== false)
|
372 |
+
{
|
373 |
+
$dom = new DOMDocument;
|
374 |
+
$createBucketConfiguration = $dom->createElement('CreateBucketConfiguration');
|
375 |
+
$locationConstraint = $dom->createElement('LocationConstraint', $location);
|
376 |
+
$createBucketConfiguration->appendChild($locationConstraint);
|
377 |
+
$dom->appendChild($createBucketConfiguration);
|
378 |
+
$rest->data = $dom->saveXML();
|
379 |
+
$rest->size = strlen($rest->data);
|
380 |
+
$rest->setHeader('Content-Type', 'application/xml');
|
381 |
+
}
|
382 |
+
$rest = $rest->getResponse();
|
383 |
+
|
384 |
+
if ($rest->error === false && $rest->code !== 200)
|
385 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
386 |
+
if ($rest->error !== false)
|
387 |
+
{
|
388 |
+
self::__triggerError(sprintf("S3::putBucket({$bucket}, {$acl}, {$location}): [%s] %s",
|
389 |
+
$rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
|
390 |
+
return false;
|
391 |
+
}
|
392 |
+
return true;
|
393 |
+
}
|
394 |
+
|
395 |
+
|
396 |
+
/**
|
397 |
+
* Delete an empty bucket
|
398 |
+
*
|
399 |
+
* @param string $bucket Bucket name
|
400 |
+
* @return boolean
|
401 |
+
*/
|
402 |
+
public static function deleteBucket($bucket)
|
403 |
+
{
|
404 |
+
$rest = new S3Request('DELETE', $bucket, '', self::$endpoint);
|
405 |
+
$rest = $rest->getResponse();
|
406 |
+
if ($rest->error === false && $rest->code !== 204)
|
407 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
408 |
+
if ($rest->error !== false)
|
409 |
+
{
|
410 |
+
self::__triggerError(sprintf("S3::deleteBucket({$bucket}): [%s] %s",
|
411 |
+
$rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
|
412 |
+
return false;
|
413 |
+
}
|
414 |
+
return true;
|
415 |
+
}
|
416 |
+
|
417 |
+
|
418 |
+
/**
|
419 |
+
* Create input info array for putObject()
|
420 |
+
*
|
421 |
+
* @param string $file Input file
|
422 |
+
* @param mixed $md5sum Use MD5 hash (supply a string if you want to use your own)
|
423 |
+
* @return array | false
|
424 |
+
*/
|
425 |
+
public static function inputFile($file, $md5sum = true)
|
426 |
+
{
|
427 |
+
if (!file_exists($file) || !is_file($file) || !is_readable($file))
|
428 |
+
{
|
429 |
+
self::__triggerError('S3::inputFile(): Unable to open input file: '.$file, __FILE__, __LINE__);
|
430 |
+
return false;
|
431 |
+
}
|
432 |
+
return array('file' => $file, 'size' => filesize($file), 'md5sum' => $md5sum !== false ?
|
433 |
+
(is_string($md5sum) ? $md5sum : base64_encode(md5_file($file, true))) : '');
|
434 |
+
}
|
435 |
+
|
436 |
+
|
437 |
+
/**
|
438 |
+
* Create input array info for putObject() with a resource
|
439 |
+
*
|
440 |
+
* @param string $resource Input resource to read from
|
441 |
+
* @param integer $bufferSize Input byte size
|
442 |
+
* @param string $md5sum MD5 hash to send (optional)
|
443 |
+
* @return array | false
|
444 |
+
*/
|
445 |
+
public static function inputResource(&$resource, $bufferSize, $md5sum = '')
|
446 |
+
{
|
447 |
+
if (!is_resource($resource) || $bufferSize < 0)
|
448 |
+
{
|
449 |
+
self::__triggerError('S3::inputResource(): Invalid resource or buffer size', __FILE__, __LINE__);
|
450 |
+
return false;
|
451 |
+
}
|
452 |
+
$input = array('size' => $bufferSize, 'md5sum' => $md5sum);
|
453 |
+
$input['fp'] =& $resource;
|
454 |
+
return $input;
|
455 |
+
}
|
456 |
+
|
457 |
+
/**
|
458 |
+
* Initiate a multi-part upload (http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadInitiate.html)
|
459 |
+
*
|
460 |
+
* @param string $bucket Bucket name
|
461 |
+
* @param string $uri Object URI
|
462 |
+
* @param constant $acl ACL constant
|
463 |
+
* @param array $metaHeaders Array of x-amz-meta-* headers
|
464 |
+
* @param array $requestHeaders Array of request headers or content type as a string
|
465 |
+
* @param constant $storageClass Storage class constant
|
466 |
+
* @return string | false
|
467 |
+
*/
|
468 |
+
|
469 |
+
public static function initiateMultipartUpload ($bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array(), $storageClass = self::STORAGE_CLASS_STANDARD)
|
470 |
+
{
|
471 |
+
|
472 |
+
$rest = new S3Request('POST', $bucket, $uri, self::$endpoint);
|
473 |
+
$rest->setParameter('uploads','');
|
474 |
+
|
475 |
+
// Custom request headers (Content-Type, Content-Disposition, Content-Encoding)
|
476 |
+
if (is_array($requestHeaders))
|
477 |
+
foreach ($requestHeaders as $h => $v) $rest->setHeader($h, $v);
|
478 |
+
|
479 |
+
// Set storage class
|
480 |
+
if ($storageClass !== self::STORAGE_CLASS_STANDARD) // Storage class
|
481 |
+
$rest->setAmzHeader('x-amz-storage-class', $storageClass);
|
482 |
+
|
483 |
+
// Set ACL headers
|
484 |
+
$rest->setAmzHeader('x-amz-acl', $acl);
|
485 |
+
foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v);
|
486 |
+
|
487 |
+
// Carry out the HTTP operation
|
488 |
+
$rest->getResponse();
|
489 |
+
|
490 |
+
if ($rest->response->error === false && $rest->response->code !== 200)
|
491 |
+
$rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status');
|
492 |
+
if ($rest->response->error !== false)
|
493 |
+
{
|
494 |
+
self::__triggerError(sprintf("S3::initiateMultipartUpload(): [%s] %s",
|
495 |
+
$rest->response->error['code'], $rest->response->error['message']), __FILE__, __LINE__);
|
496 |
+
return false;
|
497 |
+
} elseif (isset($rest->response->body))
|
498 |
+
{
|
499 |
+
$body = new SimpleXMLElement($rest->response->body);
|
500 |
+
return (string) $body->UploadId;
|
501 |
+
}
|
502 |
+
|
503 |
+
// It is a programming error if we reach this line
|
504 |
+
return false;
|
505 |
+
|
506 |
+
}
|
507 |
+
|
508 |
+
/**
|
509 |
+
/* Upload a part of a multi-part set (http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadUploadPart.html)
|
510 |
+
* The chunk is read into memory, so make sure that you have enough (or patch this function to work another way!)
|
511 |
+
*
|
512 |
+
* @param string $bucket Bucket name
|
513 |
+
* @param string $uri Object URI
|
514 |
+
* @param string $uploadId uploadId returned previously from initiateMultipartUpload
|
515 |
+
* @param integer $partNumber sequential part number to upload
|
516 |
+
* @param string $filePath file to upload content from
|
517 |
+
* @param integer $partSize number of bytes in each part (though final part may have fewer) - pass the same value each time (for this particular upload) - default 5Mb (which is Amazon's minimum)
|
518 |
+
* @return string (ETag) | false
|
519 |
+
*/
|
520 |
+
|
521 |
+
public static function uploadPart ($bucket, $uri, $uploadId, $filePath, $partNumber, $partSize = 5242880)
|
522 |
+
{
|
523 |
+
|
524 |
+
$rest = new S3Request('PUT', $bucket, $uri, self::$endpoint);
|
525 |
+
$rest->setParameter('partNumber', $partNumber);
|
526 |
+
$rest->setParameter('uploadId', $uploadId);
|
527 |
+
|
528 |
+
// Where to begin
|
529 |
+
$fileOffset = ($partNumber - 1 ) * $partSize;
|
530 |
+
|
531 |
+
// Download the smallest of the remaining bytes and the part size
|
532 |
+
$fileBytes = min(filesize($filePath) - $fileOffset, $partSize);
|
533 |
+
if ($fileBytes < 0) $fileBytes = 0;
|
534 |
+
|
535 |
+
$rest->setHeader('Content-Type', 'application/octet-stream');
|
536 |
+
$rest->data = "";
|
537 |
+
|
538 |
+
if ($handle = fopen($filePath, "rb")) {
|
539 |
+
if ($fileOffset >0) fseek($handle, $fileOffset);
|
540 |
+
$bytes_read = 0;
|
541 |
+
while ($fileBytes>0 && $read = fread($handle, max($fileBytes, 65536))) {
|
542 |
+
$fileBytes = $fileBytes - strlen($read);
|
543 |
+
$bytes_read += strlen($read);
|
544 |
+
$rest->data = $rest->data . $read;
|
545 |
+
}
|
546 |
+
fclose($handle);
|
547 |
+
} else {
|
548 |
+
return false;
|
549 |
+
}
|
550 |
+
|
551 |
+
$rest->setHeader('Content-MD5', base64_encode(md5($rest->data, true)));
|
552 |
+
$rest->size = $bytes_read;
|
553 |
+
|
554 |
+
$rest = $rest->getResponse();
|
555 |
+
if ($rest->error === false && $rest->code !== 200)
|
556 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
557 |
+
if ($rest->error !== false)
|
558 |
+
{
|
559 |
+
self::__triggerError(sprintf("S3::uploadPart(): [%s] %s",
|
560 |
+
$rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
|
561 |
+
return false;
|
562 |
+
}
|
563 |
+
return $rest->headers['hash'];
|
564 |
+
|
565 |
+
}
|
566 |
+
|
567 |
+
/**
|
568 |
+
* Complete a multi-part upload (http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadComplete.html)
|
569 |
+
*
|
570 |
+
* @param string $bucket Bucket name
|
571 |
+
* @param string $uri Object URI
|
572 |
+
* @param string $uploadId uploadId returned previously from initiateMultipartUpload
|
573 |
+
* @param array $parts an ordered list of eTags of previously uploaded parts from uploadPart
|
574 |
+
* @return boolean
|
575 |
+
*/
|
576 |
+
|
577 |
+
public static function completeMultipartUpload ($bucket, $uri, $uploadId, $parts)
|
578 |
+
{
|
579 |
+
$rest = new S3Request('POST', $bucket, $uri, self::$endpoint);
|
580 |
+
$rest->setParameter('uploadId', $uploadId);
|
581 |
+
|
582 |
+
$xml = "<CompleteMultipartUpload>\n";
|
583 |
+
$partno = 1;
|
584 |
+
foreach ($parts as $etag) {
|
585 |
+
$xml .= "<Part><PartNumber>$partno</PartNumber><ETag>$etag</ETag></Part>\n";
|
586 |
+
$partno++;
|
587 |
+
}
|
588 |
+
$xml .= "</CompleteMultipartUpload>";
|
589 |
+
|
590 |
+
$rest->data = $xml;
|
591 |
+
$rest->size = strlen($rest->data);
|
592 |
+
$rest->setHeader('Content-Type', 'application/xml');
|
593 |
+
|
594 |
+
$rest = $rest->getResponse();
|
595 |
+
if ($rest->error === false && $rest->code !== 200)
|
596 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
597 |
+
if ($rest->error !== false)
|
598 |
+
{
|
599 |
+
self::__triggerError(sprintf("S3::completeMultipartUpload(): [%s] %s",
|
600 |
+
$rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
|
601 |
+
return false;
|
602 |
+
}
|
603 |
+
return true;
|
604 |
+
|
605 |
+
}
|
606 |
+
|
607 |
+
/**
|
608 |
+
* Abort a multi-part upload (http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadAbort.html)
|
609 |
+
*
|
610 |
+
* @param string $bucket Bucket name
|
611 |
+
* @param string $uri Object URI
|
612 |
+
* @param string $uploadId uploadId returned previously from initiateMultipartUpload
|
613 |
+
* @return boolean
|
614 |
+
*/
|
615 |
+
|
616 |
+
public static function abortMultipartUpload ($bucket, $uri, $uploadId)
|
617 |
+
{
|
618 |
+
$rest = new S3Request('DELETE', $bucket, $uri, self::$endpoint);
|
619 |
+
$rest->setParameter('uploadId', $uploadId);
|
620 |
+
$rest = $rest->getResponse();
|
621 |
+
if ($rest->error === false && $rest->code !== 204)
|
622 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
623 |
+
if ($rest->error !== false)
|
624 |
+
{
|
625 |
+
self::__triggerError(sprintf("S3::abortMultipartUpload(): [%s] %s",
|
626 |
+
$rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
|
627 |
+
return false;
|
628 |
+
}
|
629 |
+
return true;
|
630 |
+
}
|
631 |
+
|
632 |
+
/**
|
633 |
+
* Put an object
|
634 |
+
*
|
635 |
+
* @param mixed $input Input data
|
636 |
+
* @param string $bucket Bucket name
|
637 |
+
* @param string $uri Object URI
|
638 |
+
* @param constant $acl ACL constant
|
639 |
+
* @param array $metaHeaders Array of x-amz-meta-* headers
|
640 |
+
* @param array $requestHeaders Array of request headers or content type as a string
|
641 |
+
* @param constant $storageClass Storage class constant
|
642 |
+
* @return boolean
|
643 |
+
*/
|
644 |
+
public static function putObject($input, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array(), $storageClass = self::STORAGE_CLASS_STANDARD)
|
645 |
+
{
|
646 |
+
if ($input === false) return false;
|
647 |
+
$rest = new S3Request('PUT', $bucket, $uri, self::$endpoint);
|
648 |
+
|
649 |
+
if (!is_array($input)) $input = array(
|
650 |
+
'data' => $input, 'size' => strlen($input),
|
651 |
+
'md5sum' => base64_encode(md5($input, true))
|
652 |
+
);
|
653 |
+
|
654 |
+
// Data
|
655 |
+
if (isset($input['fp']))
|
656 |
+
$rest->fp =& $input['fp'];
|
657 |
+
elseif (isset($input['file']) && is_file($input['file']))
|
658 |
+
$rest->fp = @fopen($input['file'], 'rb');
|
659 |
+
elseif (isset($input['data']))
|
660 |
+
$rest->data = $input['data'];
|
661 |
+
|
662 |
+
// Content-Length (required)
|
663 |
+
if (isset($input['size']) && $input['size'] >= 0)
|
664 |
+
$rest->size = $input['size'];
|
665 |
+
else {
|
666 |
+
if (isset($input['file']))
|
667 |
+
$rest->size = filesize($input['file']);
|
668 |
+
elseif (isset($input['data']))
|
669 |
+
$rest->size = strlen($input['data']);
|
670 |
+
}
|
671 |
+
|
672 |
+
// Custom request headers (Content-Type, Content-Disposition, Content-Encoding)
|
673 |
+
if (is_array($requestHeaders))
|
674 |
+
foreach ($requestHeaders as $h => $v) $rest->setHeader($h, $v);
|
675 |
+
elseif (is_string($requestHeaders)) // Support for legacy contentType parameter
|
676 |
+
$input['type'] = $requestHeaders;
|
677 |
+
|
678 |
+
// Content-Type
|
679 |
+
if (!isset($input['type']))
|
680 |
+
{
|
681 |
+
if (isset($requestHeaders['Content-Type']))
|
682 |
+
$input['type'] =& $requestHeaders['Content-Type'];
|
683 |
+
elseif (isset($input['file']))
|
684 |
+
$input['type'] = self::__getMimeType($input['file']);
|
685 |
+
else
|
686 |
+
$input['type'] = 'application/octet-stream';
|
687 |
+
}
|
688 |
+
|
689 |
+
if ($storageClass !== self::STORAGE_CLASS_STANDARD) // Storage class
|
690 |
+
$rest->setAmzHeader('x-amz-storage-class', $storageClass);
|
691 |
+
|
692 |
+
// We need to post with Content-Length and Content-Type, MD5 is optional
|
693 |
+
if ($rest->size >= 0 && ($rest->fp !== false || $rest->data !== false))
|
694 |
+
{
|
695 |
+
$rest->setHeader('Content-Type', $input['type']);
|
696 |
+
if (isset($input['md5sum'])) $rest->setHeader('Content-MD5', $input['md5sum']);
|
697 |
+
|
698 |
+
$rest->setAmzHeader('x-amz-acl', $acl);
|
699 |
+
foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v);
|
700 |
+
$rest->getResponse();
|
701 |
+
} else
|
702 |
+
$rest->response->error = array('code' => 0, 'message' => 'Missing input parameters');
|
703 |
+
|
704 |
+
if ($rest->response->error === false && $rest->response->code !== 200)
|
705 |
+
$rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status');
|
706 |
+
if ($rest->response->error !== false)
|
707 |
+
{
|
708 |
+
self::__triggerError(sprintf("S3::putObject(): [%s] %s",
|
709 |
+
$rest->response->error['code'], $rest->response->error['message']), __FILE__, __LINE__);
|
710 |
+
return false;
|
711 |
+
}
|
712 |
+
return true;
|
713 |
+
}
|
714 |
+
|
715 |
+
|
716 |
+
/**
|
717 |
+
* Put an object from a file (legacy function)
|
718 |
+
*
|
719 |
+
* @param string $file Input file path
|
720 |
+
* @param string $bucket Bucket name
|
721 |
+
* @param string $uri Object URI
|
722 |
+
* @param constant $acl ACL constant
|
723 |
+
* @param array $metaHeaders Array of x-amz-meta-* headers
|
724 |
+
* @param string $contentType Content type
|
725 |
+
* @return boolean
|
726 |
+
*/
|
727 |
+
public static function putObjectFile($file, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = null)
|
728 |
+
{
|
729 |
+
return self::putObject(self::inputFile($file), $bucket, $uri, $acl, $metaHeaders, $contentType);
|
730 |
+
}
|
731 |
+
|
732 |
+
|
733 |
+
/**
|
734 |
+
* Put an object from a string (legacy function)
|
735 |
+
*
|
736 |
+
* @param string $string Input data
|
737 |
+
* @param string $bucket Bucket name
|
738 |
+
* @param string $uri Object URI
|
739 |
+
* @param constant $acl ACL constant
|
740 |
+
* @param array $metaHeaders Array of x-amz-meta-* headers
|
741 |
+
* @param string $contentType Content type
|
742 |
+
* @return boolean
|
743 |
+
*/
|
744 |
+
public static function putObjectString($string, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = 'text/plain')
|
745 |
+
{
|
746 |
+
return self::putObject($string, $bucket, $uri, $acl, $metaHeaders, $contentType);
|
747 |
+
}
|
748 |
+
|
749 |
+
|
750 |
+
/**
|
751 |
+
* Get an object
|
752 |
+
*
|
753 |
+
* @param string $bucket Bucket name
|
754 |
+
* @param string $uri Object URI
|
755 |
+
* @param mixed $saveTo Filename or resource to write to
|
756 |
+
* @return mixed
|
757 |
+
*/
|
758 |
+
public static function getObject($bucket, $uri, $saveTo = false)
|
759 |
+
{
|
760 |
+
$rest = new S3Request('GET', $bucket, $uri, self::$endpoint);
|
761 |
+
if ($saveTo !== false)
|
762 |
+
{
|
763 |
+
if (is_resource($saveTo))
|
764 |
+
$rest->fp =& $saveTo;
|
765 |
+
else
|
766 |
+
if (($rest->fp = @fopen($saveTo, 'wb')) !== false)
|
767 |
+
$rest->file = realpath($saveTo);
|
768 |
+
else
|
769 |
+
$rest->response->error = array('code' => 0, 'message' => 'Unable to open save file for writing: '.$saveTo);
|
770 |
+
}
|
771 |
+
if ($rest->response->error === false) $rest->getResponse();
|
772 |
+
|
773 |
+
if ($rest->response->error === false && $rest->response->code !== 200)
|
774 |
+
$rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status');
|
775 |
+
if ($rest->response->error !== false)
|
776 |
+
{
|
777 |
+
self::__triggerError(sprintf("S3::getObject({$bucket}, {$uri}): [%s] %s",
|
778 |
+
$rest->response->error['code'], $rest->response->error['message']), __FILE__, __LINE__);
|
779 |
+
return false;
|
780 |
+
}
|
781 |
+
return $rest->response;
|
782 |
+
}
|
783 |
+
|
784 |
+
|
785 |
+
/**
|
786 |
+
* Get object information
|
787 |
+
*
|
788 |
+
* @param string $bucket Bucket name
|
789 |
+
* @param string $uri Object URI
|
790 |
+
* @param boolean $returnInfo Return response information
|
791 |
+
* @return mixed | false
|
792 |
+
*/
|
793 |
+
public static function getObjectInfo($bucket, $uri, $returnInfo = true)
|
794 |
+
{
|
795 |
+
$rest = new S3Request('HEAD', $bucket, $uri, self::$endpoint);
|
796 |
+
$rest = $rest->getResponse();
|
797 |
+
if ($rest->error === false && ($rest->code !== 200 && $rest->code !== 404))
|
798 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
799 |
+
if ($rest->error !== false)
|
800 |
+
{
|
801 |
+
self::__triggerError(sprintf("S3::getObjectInfo({$bucket}, {$uri}): [%s] %s",
|
802 |
+
$rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
|
803 |
+
return false;
|
804 |
+
}
|
805 |
+
return $rest->code == 200 ? $returnInfo ? $rest->headers : true : false;
|
806 |
+
}
|
807 |
+
|
808 |
+
|
809 |
+
/**
|
810 |
+
* Copy an object
|
811 |
+
*
|
812 |
+
* @param string $bucket Source bucket name
|
813 |
+
* @param string $uri Source object URI
|
814 |
+
* @param string $bucket Destination bucket name
|
815 |
+
* @param string $uri Destination object URI
|
816 |
+
* @param constant $acl ACL constant
|
817 |
+
* @param array $metaHeaders Optional array of x-amz-meta-* headers
|
818 |
+
* @param array $requestHeaders Optional array of request headers (content type, disposition, etc.)
|
819 |
+
* @param constant $storageClass Storage class constant
|
820 |
+
* @return mixed | false
|
821 |
+
*/
|
822 |
+
public static function copyObject($srcBucket, $srcUri, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array(), $storageClass = self::STORAGE_CLASS_STANDARD)
|
823 |
+
{
|
824 |
+
$rest = new S3Request('PUT', $bucket, $uri, self::$endpoint);
|
825 |
+
$rest->setHeader('Content-Length', 0);
|
826 |
+
foreach ($requestHeaders as $h => $v) $rest->setHeader($h, $v);
|
827 |
+
foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v);
|
828 |
+
if ($storageClass !== self::STORAGE_CLASS_STANDARD) // Storage class
|
829 |
+
$rest->setAmzHeader('x-amz-storage-class', $storageClass);
|
830 |
+
$rest->setAmzHeader('x-amz-acl', $acl);
|
831 |
+
$rest->setAmzHeader('x-amz-copy-source', sprintf('/%s/%s', $srcBucket, rawurlencode($srcUri)));
|
832 |
+
if (sizeof($requestHeaders) > 0 || sizeof($metaHeaders) > 0)
|
833 |
+
$rest->setAmzHeader('x-amz-metadata-directive', 'REPLACE');
|
834 |
+
|
835 |
+
$rest = $rest->getResponse();
|
836 |
+
if ($rest->error === false && $rest->code !== 200)
|
837 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
838 |
+
if ($rest->error !== false)
|
839 |
+
{
|
840 |
+
self::__triggerError(sprintf("S3::copyObject({$srcBucket}, {$srcUri}, {$bucket}, {$uri}): [%s] %s",
|
841 |
+
$rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
|
842 |
+
return false;
|
843 |
+
}
|
844 |
+
return isset($rest->body->LastModified, $rest->body->ETag) ? array(
|
845 |
+
'time' => strtotime((string)$rest->body->LastModified),
|
846 |
+
'hash' => substr((string)$rest->body->ETag, 1, -1)
|
847 |
+
) : false;
|
848 |
+
}
|
849 |
+
|
850 |
+
|
851 |
+
/**
|
852 |
+
* Set logging for a bucket
|
853 |
+
*
|
854 |
+
* @param string $bucket Bucket name
|
855 |
+
* @param string $targetBucket Target bucket (where logs are stored)
|
856 |
+
* @param string $targetPrefix Log prefix (e,g; domain.com-)
|
857 |
+
* @return boolean
|
858 |
+
*/
|
859 |
+
public static function setBucketLogging($bucket, $targetBucket, $targetPrefix = null)
|
860 |
+
{
|
861 |
+
// The S3 log delivery group has to be added to the target bucket's ACP
|
862 |
+
if ($targetBucket !== null && ($acp = self::getAccessControlPolicy($targetBucket, '')) !== false)
|
863 |
+
{
|
864 |
+
// Only add permissions to the target bucket when they do not exist
|
865 |
+
$aclWriteSet = false;
|
866 |
+
$aclReadSet = false;
|
867 |
+
foreach ($acp['acl'] as $acl)
|
868 |
+
if ($acl['type'] == 'Group' && $acl['uri'] == 'http://acs.amazonaws.com/groups/s3/LogDelivery')
|
869 |
+
{
|
870 |
+
if ($acl['permission'] == 'WRITE') $aclWriteSet = true;
|
871 |
+
elseif ($acl['permission'] == 'READ_ACP') $aclReadSet = true;
|
872 |
+
}
|
873 |
+
if (!$aclWriteSet) $acp['acl'][] = array(
|
874 |
+
'type' => 'Group', 'uri' => 'http://acs.amazonaws.com/groups/s3/LogDelivery', 'permission' => 'WRITE'
|
875 |
+
);
|
876 |
+
if (!$aclReadSet) $acp['acl'][] = array(
|
877 |
+
'type' => 'Group', 'uri' => 'http://acs.amazonaws.com/groups/s3/LogDelivery', 'permission' => 'READ_ACP'
|
878 |
+
);
|
879 |
+
if (!$aclReadSet || !$aclWriteSet) self::setAccessControlPolicy($targetBucket, '', $acp);
|
880 |
+
}
|
881 |
+
|
882 |
+
$dom = new DOMDocument;
|
883 |
+
$bucketLoggingStatus = $dom->createElement('BucketLoggingStatus');
|
884 |
+
$bucketLoggingStatus->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/');
|
885 |
+
if ($targetBucket !== null)
|
886 |
+
{
|
887 |
+
if ($targetPrefix == null) $targetPrefix = $bucket . '-';
|
888 |
+
$loggingEnabled = $dom->createElement('LoggingEnabled');
|
889 |
+
$loggingEnabled->appendChild($dom->createElement('TargetBucket', $targetBucket));
|
890 |
+
$loggingEnabled->appendChild($dom->createElement('TargetPrefix', $targetPrefix));
|
891 |
+
// TODO: Add TargetGrants?
|
892 |
+
$bucketLoggingStatus->appendChild($loggingEnabled);
|
893 |
+
}
|
894 |
+
$dom->appendChild($bucketLoggingStatus);
|
895 |
+
|
896 |
+
$rest = new S3Request('PUT', $bucket, '', self::$endpoint);
|
897 |
+
$rest->setParameter('logging', null);
|
898 |
+
$rest->data = $dom->saveXML();
|
899 |
+
$rest->size = strlen($rest->data);
|
900 |
+
$rest->setHeader('Content-Type', 'application/xml');
|
901 |
+
$rest = $rest->getResponse();
|
902 |
+
if ($rest->error === false && $rest->code !== 200)
|
903 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
904 |
+
if ($rest->error !== false)
|
905 |
+
{
|
906 |
+
self::__triggerError(sprintf("S3::setBucketLogging({$bucket}, {$targetBucket}): [%s] %s",
|
907 |
+
$rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
|
908 |
+
return false;
|
909 |
+
}
|
910 |
+
return true;
|
911 |
+
}
|
912 |
+
|
913 |
+
|
914 |
+
/**
|
915 |
+
* Get logging status for a bucket
|
916 |
+
*
|
917 |
+
* This will return false if logging is not enabled.
|
918 |
+
* Note: To enable logging, you also need to grant write access to the log group
|
919 |
+
*
|
920 |
+
* @param string $bucket Bucket name
|
921 |
+
* @return array | false
|
922 |
+
*/
|
923 |
+
public static function getBucketLogging($bucket)
|
924 |
+
{
|
925 |
+
$rest = new S3Request('GET', $bucket, '', self::$endpoint);
|
926 |
+
$rest->setParameter('logging', null);
|
927 |
+
$rest = $rest->getResponse();
|
928 |
+
if ($rest->error === false && $rest->code !== 200)
|
929 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
930 |
+
if ($rest->error !== false)
|
931 |
+
{
|
932 |
+
self::__triggerError(sprintf("S3::getBucketLogging({$bucket}): [%s] %s",
|
933 |
+
$rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
|
934 |
+
return false;
|
935 |
+
}
|
936 |
+
if (!isset($rest->body->LoggingEnabled)) return false; // No logging
|
937 |
+
return array(
|
938 |
+
'targetBucket' => (string)$rest->body->LoggingEnabled->TargetBucket,
|
939 |
+
'targetPrefix' => (string)$rest->body->LoggingEnabled->TargetPrefix,
|
940 |
+
);
|
941 |
+
}
|
942 |
+
|
943 |
+
|
944 |
+
/**
|
945 |
+
* Disable bucket logging
|
946 |
+
*
|
947 |
+
* @param string $bucket Bucket name
|
948 |
+
* @return boolean
|
949 |
+
*/
|
950 |
+
public static function disableBucketLogging($bucket)
|
951 |
+
{
|
952 |
+
return self::setBucketLogging($bucket, null);
|
953 |
+
}
|
954 |
+
|
955 |
+
|
956 |
+
/**
|
957 |
+
* Get a bucket's location
|
958 |
+
*
|
959 |
+
* @param string $bucket Bucket name
|
960 |
+
* @return string | false
|
961 |
+
*/
|
962 |
+
public static function getBucketLocation($bucket)
|
963 |
+
{
|
964 |
+
$rest = new S3Request('GET', $bucket, '', self::$endpoint);
|
965 |
+
$rest->setParameter('location', null);
|
966 |
+
$rest = $rest->getResponse();
|
967 |
+
if ($rest->error === false && $rest->code !== 200)
|
968 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
969 |
+
if ($rest->error !== false)
|
970 |
+
{
|
971 |
+
self::__triggerError(sprintf("S3::getBucketLocation({$bucket}): [%s] %s",
|
972 |
+
$rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
|
973 |
+
return false;
|
974 |
+
}
|
975 |
+
return (isset($rest->body[0]) && (string)$rest->body[0] !== '') ? (string)$rest->body[0] : 'US';
|
976 |
+
}
|
977 |
+
|
978 |
+
|
979 |
+
/**
|
980 |
+
* Set object or bucket Access Control Policy
|
981 |
+
*
|
982 |
+
* @param string $bucket Bucket name
|
983 |
+
* @param string $uri Object URI
|
984 |
+
* @param array $acp Access Control Policy Data (same as the data returned from getAccessControlPolicy)
|
985 |
+
* @return boolean
|
986 |
+
*/
|
987 |
+
public static function setAccessControlPolicy($bucket, $uri = '', $acp = array())
|
988 |
+
{
|
989 |
+
$dom = new DOMDocument;
|
990 |
+
$dom->formatOutput = true;
|
991 |
+
$accessControlPolicy = $dom->createElement('AccessControlPolicy');
|
992 |
+
$accessControlList = $dom->createElement('AccessControlList');
|
993 |
+
|
994 |
+
// It seems the owner has to be passed along too
|
995 |
+
$owner = $dom->createElement('Owner');
|
996 |
+
$owner->appendChild($dom->createElement('ID', $acp['owner']['id']));
|
997 |
+
$owner->appendChild($dom->createElement('DisplayName', $acp['owner']['name']));
|
998 |
+
$accessControlPolicy->appendChild($owner);
|
999 |
+
|
1000 |
+
foreach ($acp['acl'] as $g)
|
1001 |
+
{
|
1002 |
+
$grant = $dom->createElement('Grant');
|
1003 |
+
$grantee = $dom->createElement('Grantee');
|
1004 |
+
$grantee->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
|
1005 |
+
if (isset($g['id']))
|
1006 |
+
{ // CanonicalUser (DisplayName is omitted)
|
1007 |
+
$grantee->setAttribute('xsi:type', 'CanonicalUser');
|
1008 |
+
$grantee->appendChild($dom->createElement('ID', $g['id']));
|
1009 |
+
}
|
1010 |
+
elseif (isset($g['email']))
|
1011 |
+
{ // AmazonCustomerByEmail
|
1012 |
+
$grantee->setAttribute('xsi:type', 'AmazonCustomerByEmail');
|
1013 |
+
$grantee->appendChild($dom->createElement('EmailAddress', $g['email']));
|
1014 |
+
}
|
1015 |
+
elseif ($g['type'] == 'Group')
|
1016 |
+
{ // Group
|
1017 |
+
$grantee->setAttribute('xsi:type', 'Group');
|
1018 |
+
$grantee->appendChild($dom->createElement('URI', $g['uri']));
|
1019 |
+
}
|
1020 |
+
$grant->appendChild($grantee);
|
1021 |
+
$grant->appendChild($dom->createElement('Permission', $g['permission']));
|
1022 |
+
$accessControlList->appendChild($grant);
|
1023 |
+
}
|
1024 |
+
|
1025 |
+
$accessControlPolicy->appendChild($accessControlList);
|
1026 |
+
$dom->appendChild($accessControlPolicy);
|
1027 |
+
|
1028 |
+
$rest = new S3Request('PUT', $bucket, $uri, self::$endpoint);
|
1029 |
+
$rest->setParameter('acl', null);
|
1030 |
+
$rest->data = $dom->saveXML();
|
1031 |
+
$rest->size = strlen($rest->data);
|
1032 |
+
$rest->setHeader('Content-Type', 'application/xml');
|
1033 |
+
$rest = $rest->getResponse();
|
1034 |
+
if ($rest->error === false && $rest->code !== 200)
|
1035 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
1036 |
+
if ($rest->error !== false)
|
1037 |
+
{
|
1038 |
+
self::__triggerError(sprintf("S3::setAccessControlPolicy({$bucket}, {$uri}): [%s] %s",
|
1039 |
+
$rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
|
1040 |
+
return false;
|
1041 |
+
}
|
1042 |
+
return true;
|
1043 |
+
}
|
1044 |
+
|
1045 |
+
|
1046 |
+
/**
|
1047 |
+
* Get object or bucket Access Control Policy
|
1048 |
+
*
|
1049 |
+
* @param string $bucket Bucket name
|
1050 |
+
* @param string $uri Object URI
|
1051 |
+
* @return mixed | false
|
1052 |
+
*/
|
1053 |
+
public static function getAccessControlPolicy($bucket, $uri = '')
|
1054 |
+
{
|
1055 |
+
$rest = new S3Request('GET', $bucket, $uri, self::$endpoint);
|
1056 |
+
$rest->setParameter('acl', null);
|
1057 |
+
$rest = $rest->getResponse();
|
1058 |
+
if ($rest->error === false && $rest->code !== 200)
|
1059 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
1060 |
+
if ($rest->error !== false)
|
1061 |
+
{
|
1062 |
+
self::__triggerError(sprintf("S3::getAccessControlPolicy({$bucket}, {$uri}): [%s] %s",
|
1063 |
+
$rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
|
1064 |
+
return false;
|
1065 |
+
}
|
1066 |
+
|
1067 |
+
$acp = array();
|
1068 |
+
if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName))
|
1069 |
+
$acp['owner'] = array(
|
1070 |
+
'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->DisplayName
|
1071 |
+
);
|
1072 |
+
|
1073 |
+
if (isset($rest->body->AccessControlList))
|
1074 |
+
{
|
1075 |
+
$acp['acl'] = array();
|
1076 |
+
foreach ($rest->body->AccessControlList->Grant as $grant)
|
1077 |
+
{
|
1078 |
+
foreach ($grant->Grantee as $grantee)
|
1079 |
+
{
|
1080 |
+
if (isset($grantee->ID, $grantee->DisplayName)) // CanonicalUser
|
1081 |
+
$acp['acl'][] = array(
|
1082 |
+
'type' => 'CanonicalUser',
|
1083 |
+
'id' => (string)$grantee->ID,
|
1084 |
+
'name' => (string)$grantee->DisplayName,
|
1085 |
+
'permission' => (string)$grant->Permission
|
1086 |
+
);
|
1087 |
+
elseif (isset($grantee->EmailAddress)) // AmazonCustomerByEmail
|
1088 |
+
$acp['acl'][] = array(
|
1089 |
+
'type' => 'AmazonCustomerByEmail',
|
1090 |
+
'email' => (string)$grantee->EmailAddress,
|
1091 |
+
'permission' => (string)$grant->Permission
|
1092 |
+
);
|
1093 |
+
elseif (isset($grantee->URI)) // Group
|
1094 |
+
$acp['acl'][] = array(
|
1095 |
+
'type' => 'Group',
|
1096 |
+
'uri' => (string)$grantee->URI,
|
1097 |
+
'permission' => (string)$grant->Permission
|
1098 |
+
);
|
1099 |
+
else continue;
|
1100 |
+
}
|
1101 |
+
}
|
1102 |
+
}
|
1103 |
+
return $acp;
|
1104 |
+
}
|
1105 |
+
|
1106 |
+
|
1107 |
+
/**
|
1108 |
+
* Delete an object
|
1109 |
+
*
|
1110 |
+
* @param string $bucket Bucket name
|
1111 |
+
* @param string $uri Object URI
|
1112 |
+
* @return boolean
|
1113 |
+
*/
|
1114 |
+
public static function deleteObject($bucket, $uri)
|
1115 |
+
{
|
1116 |
+
$rest = new S3Request('DELETE', $bucket, $uri, self::$endpoint);
|
1117 |
+
$rest = $rest->getResponse();
|
1118 |
+
if ($rest->error === false && $rest->code !== 204)
|
1119 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
1120 |
+
if ($rest->error !== false)
|
1121 |
+
{
|
1122 |
+
self::__triggerError(sprintf("S3::deleteObject(): [%s] %s",
|
1123 |
+
$rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
|
1124 |
+
return false;
|
1125 |
+
}
|
1126 |
+
return true;
|
1127 |
+
}
|
1128 |
+
|
1129 |
+
|
1130 |
+
/**
|
1131 |
+
* Get a query string authenticated URL
|
1132 |
+
*
|
1133 |
+
* @param string $bucket Bucket name
|
1134 |
+
* @param string $uri Object URI
|
1135 |
+
* @param integer $lifetime Lifetime in seconds
|
1136 |
+
* @param boolean $hostBucket Use the bucket name as the hostname
|
1137 |
+
* @param boolean $https Use HTTPS ($hostBucket should be false for SSL verification)
|
1138 |
+
* @return string
|
1139 |
+
*/
|
1140 |
+
public static function getAuthenticatedURL($bucket, $uri, $lifetime, $hostBucket = false, $https = false)
|
1141 |
+
{
|
1142 |
+
$expires = time() + $lifetime;
|
1143 |
+
$uri = str_replace(array('%2F', '%2B'), array('/', '+'), rawurlencode($uri));
|
1144 |
+
return sprintf(($https ? 'https' : 'http').'://%s/%s?AWSAccessKeyId=%s&Expires=%u&Signature=%s',
|
1145 |
+
// $hostBucket ? $bucket : $bucket.'.s3.amazonaws.com', $uri, self::$__accessKey, $expires,
|
1146 |
+
$hostBucket ? $bucket : 's3.amazonaws.com/'.$bucket, $uri, self::$__accessKey, $expires,
|
1147 |
+
urlencode(self::__getHash("GET\n\n\n{$expires}\n/{$bucket}/{$uri}")));
|
1148 |
+
}
|
1149 |
+
|
1150 |
+
|
1151 |
+
/**
|
1152 |
+
* Get a CloudFront signed policy URL
|
1153 |
+
*
|
1154 |
+
* @param array $policy Policy
|
1155 |
+
* @return string
|
1156 |
+
*/
|
1157 |
+
public static function getSignedPolicyURL($policy)
|
1158 |
+
{
|
1159 |
+
$data = json_encode($policy);
|
1160 |
+
$signature = '';
|
1161 |
+
if (!openssl_sign($data, $signature, self::$__signingKeyResource)) return false;
|
1162 |
+
|
1163 |
+
$encoded = str_replace(array('+', '='), array('-', '_', '~'), base64_encode($data));
|
1164 |
+
$signature = str_replace(array('+', '='), array('-', '_', '~'), base64_encode($signature));
|
1165 |
+
|
1166 |
+
$url = $policy['Statement'][0]['Resource'] . '?';
|
1167 |
+
foreach (array('Policy' => $encoded, 'Signature' => $signature, 'Key-Pair-Id' => self::$__signingKeyPairId) as $k => $v)
|
1168 |
+
$url .= $k.'='.str_replace('%2F', '/', rawurlencode($v)).'&';
|
1169 |
+
return substr($url, 0, -1);
|
1170 |
+
}
|
1171 |
+
|
1172 |
+
|
1173 |
+
/**
|
1174 |
+
* Get a CloudFront canned policy URL
|
1175 |
+
*
|
1176 |
+
* @param string $string URL to sign
|
1177 |
+
* @param integer $lifetime URL lifetime
|
1178 |
+
* @return string
|
1179 |
+
*/
|
1180 |
+
public static function getSignedCannedURL($url, $lifetime)
|
1181 |
+
{
|
1182 |
+
return self::getSignedPolicyURL(array(
|
1183 |
+
'Statement' => array(
|
1184 |
+
array('Resource' => $url, 'Condition' => array(
|
1185 |
+
'DateLessThan' => array('AWS:EpochTime' => time() + $lifetime)
|
1186 |
+
))
|
1187 |
+
)
|
1188 |
+
));
|
1189 |
+
}
|
1190 |
+
|
1191 |
+
|
1192 |
+
/**
|
1193 |
+
* Get upload POST parameters for form uploads
|
1194 |
+
*
|
1195 |
+
* @param string $bucket Bucket name
|
1196 |
+
* @param string $uriPrefix Object URI prefix
|
1197 |
+
* @param constant $acl ACL constant
|
1198 |
+
* @param integer $lifetime Lifetime in seconds
|
1199 |
+
* @param integer $maxFileSize Maximum filesize in bytes (default 5MB)
|
1200 |
+
* @param string $successRedirect Redirect URL or 200 / 201 status code
|
1201 |
+
* @param array $amzHeaders Array of x-amz-meta-* headers
|
1202 |
+
* @param array $headers Array of request headers or content type as a string
|
1203 |
+
* @param boolean $flashVars Includes additional "Filename" variable posted by Flash
|
1204 |
+
* @return object
|
1205 |
+
*/
|
1206 |
+
public static function getHttpUploadPostParams($bucket, $uriPrefix = '', $acl = self::ACL_PRIVATE, $lifetime = 3600,
|
1207 |
+
$maxFileSize = 5242880, $successRedirect = "201", $amzHeaders = array(), $headers = array(), $flashVars = false)
|
1208 |
+
{
|
1209 |
+
// Create policy object
|
1210 |
+
$policy = new stdClass;
|
1211 |
+
$policy->expiration = gmdate('Y-m-d\TH:i:s\Z', (time() + $lifetime));
|
1212 |
+
$policy->conditions = array();
|
1213 |
+
$obj = new stdClass; $obj->bucket = $bucket; array_push($policy->conditions, $obj);
|
1214 |
+
$obj = new stdClass; $obj->acl = $acl; array_push($policy->conditions, $obj);
|
1215 |
+
|
1216 |
+
$obj = new stdClass; // 200 for non-redirect uploads
|
1217 |
+
if (is_numeric($successRedirect) && in_array((int)$successRedirect, array(200, 201)))
|
1218 |
+
$obj->success_action_status = (string)$successRedirect;
|
1219 |
+
else // URL
|
1220 |
+
$obj->success_action_redirect = $successRedirect;
|
1221 |
+
array_push($policy->conditions, $obj);
|
1222 |
+
|
1223 |
+
if ($acl !== self::ACL_PUBLIC_READ)
|
1224 |
+
array_push($policy->conditions, array('eq', '$acl', $acl));
|
1225 |
+
|
1226 |
+
array_push($policy->conditions, array('starts-with', '$key', $uriPrefix));
|
1227 |
+
if ($flashVars) array_push($policy->conditions, array('starts-with', '$Filename', ''));
|
1228 |
+
foreach (array_keys($headers) as $headerKey)
|
1229 |
+
array_push($policy->conditions, array('starts-with', '$'.$headerKey, ''));
|
1230 |
+
foreach ($amzHeaders as $headerKey => $headerVal)
|
1231 |
+
{
|
1232 |
+
$obj = new stdClass;
|
1233 |
+
$obj->{$headerKey} = (string)$headerVal;
|
1234 |
+
array_push($policy->conditions, $obj);
|
1235 |
+
}
|
1236 |
+
array_push($policy->conditions, array('content-length-range', 0, $maxFileSize));
|
1237 |
+
$policy = base64_encode(str_replace('\/', '/', json_encode($policy)));
|
1238 |
+
|
1239 |
+
// Create parameters
|
1240 |
+
$params = new stdClass;
|
1241 |
+
$params->AWSAccessKeyId = self::$__accessKey;
|
1242 |
+
$params->key = $uriPrefix.'${filename}';
|
1243 |
+
$params->acl = $acl;
|
1244 |
+
$params->policy = $policy; unset($policy);
|
1245 |
+
$params->signature = self::__getHash($params->policy);
|
1246 |
+
if (is_numeric($successRedirect) && in_array((int)$successRedirect, array(200, 201)))
|
1247 |
+
$params->success_action_status = (string)$successRedirect;
|
1248 |
+
else
|
1249 |
+
$params->success_action_redirect = $successRedirect;
|
1250 |
+
foreach ($headers as $headerKey => $headerVal) $params->{$headerKey} = (string)$headerVal;
|
1251 |
+
foreach ($amzHeaders as $headerKey => $headerVal) $params->{$headerKey} = (string)$headerVal;
|
1252 |
+
return $params;
|
1253 |
+
}
|
1254 |
+
|
1255 |
+
|
1256 |
+
/**
|
1257 |
+
* Create a CloudFront distribution
|
1258 |
+
*
|
1259 |
+
* @param string $bucket Bucket name
|
1260 |
+
* @param boolean $enabled Enabled (true/false)
|
1261 |
+
* @param array $cnames Array containing CNAME aliases
|
1262 |
+
* @param string $comment Use the bucket name as the hostname
|
1263 |
+
* @param string $defaultRootObject Default root object
|
1264 |
+
* @param string $originAccessIdentity Origin access identity
|
1265 |
+
* @param array $trustedSigners Array of trusted signers
|
1266 |
+
* @return array | false
|
1267 |
+
*/
|
1268 |
+
public static function createDistribution($bucket, $enabled = true, $cnames = array(), $comment = null, $defaultRootObject = null, $originAccessIdentity = null, $trustedSigners = array())
|
1269 |
+
{
|
1270 |
+
if (!extension_loaded('openssl'))
|
1271 |
+
{
|
1272 |
+
self::__triggerError(sprintf("S3::createDistribution({$bucket}, ".(int)$enabled.", [], '$comment'): %s",
|
1273 |
+
"CloudFront functionality requires SSL"), __FILE__, __LINE__);
|
1274 |
+
return false;
|
1275 |
+
}
|
1276 |
+
$useSSL = self::$useSSL;
|
1277 |
+
|
1278 |
+
self::$useSSL = true; // CloudFront requires SSL
|
1279 |
+
$rest = new S3Request('POST', '', '2010-11-01/distribution', 'cloudfront.amazonaws.com');
|
1280 |
+
$rest->data = self::__getCloudFrontDistributionConfigXML(
|
1281 |
+
$bucket.'.s3.amazonaws.com',
|
1282 |
+
$enabled,
|
1283 |
+
(string)$comment,
|
1284 |
+
(string)microtime(true),
|
1285 |
+
$cnames,
|
1286 |
+
$defaultRootObject,
|
1287 |
+
$originAccessIdentity,
|
1288 |
+
$trustedSigners
|
1289 |
+
);
|
1290 |
+
|
1291 |
+
$rest->size = strlen($rest->data);
|
1292 |
+
$rest->setHeader('Content-Type', 'application/xml');
|
1293 |
+
$rest = self::__getCloudFrontResponse($rest);
|
1294 |
+
|
1295 |
+
self::$useSSL = $useSSL;
|
1296 |
+
|
1297 |
+
if ($rest->error === false && $rest->code !== 201)
|
1298 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
1299 |
+
if ($rest->error !== false)
|
1300 |
+
{
|
1301 |
+
self::__triggerError(sprintf("S3::createDistribution({$bucket}, ".(int)$enabled.", [], '$comment'): [%s] %s",
|
1302 |
+
$rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
|
1303 |
+
return false;
|
1304 |
+
} elseif ($rest->body instanceof SimpleXMLElement)
|
1305 |
+
return self::__parseCloudFrontDistributionConfig($rest->body);
|
1306 |
+
return false;
|
1307 |
+
}
|
1308 |
+
|
1309 |
+
|
1310 |
+
/**
|
1311 |
+
* Get CloudFront distribution info
|
1312 |
+
*
|
1313 |
+
* @param string $distributionId Distribution ID from listDistributions()
|
1314 |
+
* @return array | false
|
1315 |
+
*/
|
1316 |
+
public static function getDistribution($distributionId)
|
1317 |
+
{
|
1318 |
+
if (!extension_loaded('openssl'))
|
1319 |
+
{
|
1320 |
+
self::__triggerError(sprintf("S3::getDistribution($distributionId): %s",
|
1321 |
+
"CloudFront functionality requires SSL"), __FILE__, __LINE__);
|
1322 |
+
return false;
|
1323 |
+
}
|
1324 |
+
$useSSL = self::$useSSL;
|
1325 |
+
|
1326 |
+
self::$useSSL = true; // CloudFront requires SSL
|
1327 |
+
$rest = new S3Request('GET', '', '2010-11-01/distribution/'.$distributionId, 'cloudfront.amazonaws.com');
|
1328 |
+
$rest = self::__getCloudFrontResponse($rest);
|
1329 |
+
|
1330 |
+
self::$useSSL = $useSSL;
|
1331 |
+
|
1332 |
+
if ($rest->error === false && $rest->code !== 200)
|
1333 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
1334 |
+
if ($rest->error !== false)
|
1335 |
+
{
|
1336 |
+
self::__triggerError(sprintf("S3::getDistribution($distributionId): [%s] %s",
|
1337 |
+
$rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
|
1338 |
+
return false;
|
1339 |
+
}
|
1340 |
+
elseif ($rest->body instanceof SimpleXMLElement)
|
1341 |
+
{
|
1342 |
+
$dist = self::__parseCloudFrontDistributionConfig($rest->body);
|
1343 |
+
$dist['hash'] = $rest->headers['hash'];
|
1344 |
+
$dist['id'] = $distributionId;
|
1345 |
+
return $dist;
|
1346 |
+
}
|
1347 |
+
return false;
|
1348 |
+
}
|
1349 |
+
|
1350 |
+
|
1351 |
+
/**
|
1352 |
+
* Update a CloudFront distribution
|
1353 |
+
*
|
1354 |
+
* @param array $dist Distribution array info identical to output of getDistribution()
|
1355 |
+
* @return array | false
|
1356 |
+
*/
|
1357 |
+
public static function updateDistribution($dist)
|
1358 |
+
{
|
1359 |
+
if (!extension_loaded('openssl'))
|
1360 |
+
{
|
1361 |
+
self::__triggerError(sprintf("S3::updateDistribution({$dist['id']}): %s",
|
1362 |
+
"CloudFront functionality requires SSL"), __FILE__, __LINE__);
|
1363 |
+
return false;
|
1364 |
+
}
|
1365 |
+
|
1366 |
+
$useSSL = self::$useSSL;
|
1367 |
+
|
1368 |
+
self::$useSSL = true; // CloudFront requires SSL
|
1369 |
+
$rest = new S3Request('PUT', '', '2010-11-01/distribution/'.$dist['id'].'/config', 'cloudfront.amazonaws.com');
|
1370 |
+
$rest->data = self::__getCloudFrontDistributionConfigXML(
|
1371 |
+
$dist['origin'],
|
1372 |
+
$dist['enabled'],
|
1373 |
+
$dist['comment'],
|
1374 |
+
$dist['callerReference'],
|
1375 |
+
$dist['cnames'],
|
1376 |
+
$dist['defaultRootObject'],
|
1377 |
+
$dist['originAccessIdentity'],
|
1378 |
+
$dist['trustedSigners']
|
1379 |
+
);
|
1380 |
+
|
1381 |
+
$rest->size = strlen($rest->data);
|
1382 |
+
$rest->setHeader('If-Match', $dist['hash']);
|
1383 |
+
$rest = self::__getCloudFrontResponse($rest);
|
1384 |
+
|
1385 |
+
self::$useSSL = $useSSL;
|
1386 |
+
|
1387 |
+
if ($rest->error === false && $rest->code !== 200)
|
1388 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
1389 |
+
if ($rest->error !== false)
|
1390 |
+
{
|
1391 |
+
self::__triggerError(sprintf("S3::updateDistribution({$dist['id']}): [%s] %s",
|
1392 |
+
$rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
|
1393 |
+
return false;
|
1394 |
+
} else {
|
1395 |
+
$dist = self::__parseCloudFrontDistributionConfig($rest->body);
|
1396 |
+
$dist['hash'] = $rest->headers['hash'];
|
1397 |
+
return $dist;
|
1398 |
+
}
|
1399 |
+
return false;
|
1400 |
+
}
|
1401 |
+
|
1402 |
+
|
1403 |
+
/**
|
1404 |
+
* Delete a CloudFront distribution
|
1405 |
+
*
|
1406 |
+
* @param array $dist Distribution array info identical to output of getDistribution()
|
1407 |
+
* @return boolean
|
1408 |
+
*/
|
1409 |
+
public static function deleteDistribution($dist)
|
1410 |
+
{
|
1411 |
+
if (!extension_loaded('openssl'))
|
1412 |
+
{
|
1413 |
+
self::__triggerError(sprintf("S3::deleteDistribution({$dist['id']}): %s",
|
1414 |
+
"CloudFront functionality requires SSL"), __FILE__, __LINE__);
|
1415 |
+
return false;
|
1416 |
+
}
|
1417 |
+
|
1418 |
+
$useSSL = self::$useSSL;
|
1419 |
+
|
1420 |
+
self::$useSSL = true; // CloudFront requires SSL
|
1421 |
+
$rest = new S3Request('DELETE', '', '2008-06-30/distribution/'.$dist['id'], 'cloudfront.amazonaws.com');
|
1422 |
+
$rest->setHeader('If-Match', $dist['hash']);
|
1423 |
+
$rest = self::__getCloudFrontResponse($rest);
|
1424 |
+
|
1425 |
+
self::$useSSL = $useSSL;
|
1426 |
+
|
1427 |
+
if ($rest->error === false && $rest->code !== 204)
|
1428 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
1429 |
+
if ($rest->error !== false)
|
1430 |
+
{
|
1431 |
+
self::__triggerError(sprintf("S3::deleteDistribution({$dist['id']}): [%s] %s",
|
1432 |
+
$rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
|
1433 |
+
return false;
|
1434 |
+
}
|
1435 |
+
return true;
|
1436 |
+
}
|
1437 |
+
|
1438 |
+
|
1439 |
+
/**
|
1440 |
+
* Get a list of CloudFront distributions
|
1441 |
+
*
|
1442 |
+
* @return array
|
1443 |
+
*/
|
1444 |
+
public static function listDistributions()
|
1445 |
+
{
|
1446 |
+
if (!extension_loaded('openssl'))
|
1447 |
+
{
|
1448 |
+
self::__triggerError(sprintf("S3::listDistributions(): [%s] %s",
|
1449 |
+
"CloudFront functionality requires SSL"), __FILE__, __LINE__);
|
1450 |
+
return false;
|
1451 |
+
}
|
1452 |
+
|
1453 |
+
$useSSL = self::$useSSL;
|
1454 |
+
self::$useSSL = true; // CloudFront requires SSL
|
1455 |
+
$rest = new S3Request('GET', '', '2010-11-01/distribution', 'cloudfront.amazonaws.com');
|
1456 |
+
$rest = self::__getCloudFrontResponse($rest);
|
1457 |
+
self::$useSSL = $useSSL;
|
1458 |
+
|
1459 |
+
if ($rest->error === false && $rest->code !== 200)
|
1460 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
1461 |
+
if ($rest->error !== false)
|
1462 |
+
{
|
1463 |
+
self::__triggerError(sprintf("S3::listDistributions(): [%s] %s",
|
1464 |
+
$rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
|
1465 |
+
return false;
|
1466 |
+
}
|
1467 |
+
elseif ($rest->body instanceof SimpleXMLElement && isset($rest->body->DistributionSummary))
|
1468 |
+
{
|
1469 |
+
$list = array();
|
1470 |
+
if (isset($rest->body->Marker, $rest->body->MaxItems, $rest->body->IsTruncated))
|
1471 |
+
{
|
1472 |
+
//$info['marker'] = (string)$rest->body->Marker;
|
1473 |
+
//$info['maxItems'] = (int)$rest->body->MaxItems;
|
1474 |
+
//$info['isTruncated'] = (string)$rest->body->IsTruncated == 'true' ? true : false;
|
1475 |
+
}
|
1476 |
+
foreach ($rest->body->DistributionSummary as $summary)
|
1477 |
+
$list[(string)$summary->Id] = self::__parseCloudFrontDistributionConfig($summary);
|
1478 |
+
|
1479 |
+
return $list;
|
1480 |
+
}
|
1481 |
+
return array();
|
1482 |
+
}
|
1483 |
+
|
1484 |
+
/**
|
1485 |
+
* List CloudFront Origin Access Identities
|
1486 |
+
*
|
1487 |
+
* @return array
|
1488 |
+
*/
|
1489 |
+
public static function listOriginAccessIdentities()
|
1490 |
+
{
|
1491 |
+
if (!extension_loaded('openssl'))
|
1492 |
+
{
|
1493 |
+
self::__triggerError(sprintf("S3::listOriginAccessIdentities(): [%s] %s",
|
1494 |
+
"CloudFront functionality requires SSL"), __FILE__, __LINE__);
|
1495 |
+
return false;
|
1496 |
+
}
|
1497 |
+
|
1498 |
+
self::$useSSL = true; // CloudFront requires SSL
|
1499 |
+
$rest = new S3Request('GET', '', '2010-11-01/origin-access-identity/cloudfront', 'cloudfront.amazonaws.com');
|
1500 |
+
$rest = self::__getCloudFrontResponse($rest);
|
1501 |
+
$useSSL = self::$useSSL;
|
1502 |
+
|
1503 |
+
if ($rest->error === false && $rest->code !== 200)
|
1504 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
1505 |
+
if ($rest->error !== false)
|
1506 |
+
{
|
1507 |
+
trigger_error(sprintf("S3::listOriginAccessIdentities(): [%s] %s",
|
1508 |
+
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
1509 |
+
return false;
|
1510 |
+
}
|
1511 |
+
|
1512 |
+
if (isset($rest->body->CloudFrontOriginAccessIdentitySummary))
|
1513 |
+
{
|
1514 |
+
$identities = array();
|
1515 |
+
foreach ($rest->body->CloudFrontOriginAccessIdentitySummary as $identity)
|
1516 |
+
if (isset($identity->S3CanonicalUserId))
|
1517 |
+
$identities[(string)$identity->Id] = array('id' => (string)$identity->Id, 's3CanonicalUserId' => (string)$identity->S3CanonicalUserId);
|
1518 |
+
return $identities;
|
1519 |
+
}
|
1520 |
+
return false;
|
1521 |
+
}
|
1522 |
+
|
1523 |
+
|
1524 |
+
/**
|
1525 |
+
* Invalidate objects in a CloudFront distribution
|
1526 |
+
*
|
1527 |
+
* Thanks to Martin Lindkvist for S3::invalidateDistribution()
|
1528 |
+
*
|
1529 |
+
* @param string $distributionId Distribution ID from listDistributions()
|
1530 |
+
* @param array $paths Array of object paths to invalidate
|
1531 |
+
* @return boolean
|
1532 |
+
*/
|
1533 |
+
public static function invalidateDistribution($distributionId, $paths)
|
1534 |
+
{
|
1535 |
+
if (!extension_loaded('openssl'))
|
1536 |
+
{
|
1537 |
+
self::__triggerError(sprintf("S3::invalidateDistribution(): [%s] %s",
|
1538 |
+
"CloudFront functionality requires SSL"), __FILE__, __LINE__);
|
1539 |
+
return false;
|
1540 |
+
}
|
1541 |
+
|
1542 |
+
$useSSL = self::$useSSL;
|
1543 |
+
self::$useSSL = true; // CloudFront requires SSL
|
1544 |
+
$rest = new S3Request('POST', '', '2010-08-01/distribution/'.$distributionId.'/invalidation', 'cloudfront.amazonaws.com');
|
1545 |
+
$rest->data = self::__getCloudFrontInvalidationBatchXML($paths, (string)microtime(true));
|
1546 |
+
$rest->size = strlen($rest->data);
|
1547 |
+
$rest = self::__getCloudFrontResponse($rest);
|
1548 |
+
self::$useSSL = $useSSL;
|
1549 |
+
|
1550 |
+
if ($rest->error === false && $rest->code !== 201)
|
1551 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
1552 |
+
if ($rest->error !== false)
|
1553 |
+
{
|
1554 |
+
trigger_error(sprintf("S3::invalidate('{$distributionId}',{$paths}): [%s] %s",
|
1555 |
+
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
1556 |
+
return false;
|
1557 |
+
}
|
1558 |
+
return true;
|
1559 |
+
}
|
1560 |
+
|
1561 |
+
|
1562 |
+
/**
|
1563 |
+
* Get a InvalidationBatch DOMDocument
|
1564 |
+
*
|
1565 |
+
* @internal Used to create XML in invalidateDistribution()
|
1566 |
+
* @param array $paths Paths to objects to invalidateDistribution
|
1567 |
+
* @return string
|
1568 |
+
*/
|
1569 |
+
private static function __getCloudFrontInvalidationBatchXML($paths, $callerReference = '0') {
|
1570 |
+
$dom = new DOMDocument('1.0', 'UTF-8');
|
1571 |
+
$dom->formatOutput = true;
|
1572 |
+
$invalidationBatch = $dom->createElement('InvalidationBatch');
|
1573 |
+
foreach ($paths as $path)
|
1574 |
+
$invalidationBatch->appendChild($dom->createElement('Path', $path));
|
1575 |
+
|
1576 |
+
$invalidationBatch->appendChild($dom->createElement('CallerReference', $callerReference));
|
1577 |
+
$dom->appendChild($invalidationBatch);
|
1578 |
+
return $dom->saveXML();
|
1579 |
+
}
|
1580 |
+
|
1581 |
+
|
1582 |
+
/**
|
1583 |
+
* List your invalidation batches for invalidateDistribution() in a CloudFront distribution
|
1584 |
+
*
|
1585 |
+
* http://docs.amazonwebservices.com/AmazonCloudFront/latest/APIReference/ListInvalidation.html
|
1586 |
+
* returned array looks like this:
|
1587 |
+
* Array
|
1588 |
+
* (
|
1589 |
+
* [I31TWB0CN9V6XD] => InProgress
|
1590 |
+
* [IT3TFE31M0IHZ] => Completed
|
1591 |
+
* [I12HK7MPO1UQDA] => Completed
|
1592 |
+
* [I1IA7R6JKTC3L2] => Completed
|
1593 |
+
* )
|
1594 |
+
*
|
1595 |
+
* @param string $distributionId Distribution ID from listDistributions()
|
1596 |
+
* @return array
|
1597 |
+
*/
|
1598 |
+
public static function getDistributionInvalidationList($distributionId)
|
1599 |
+
{
|
1600 |
+
if (!extension_loaded('openssl'))
|
1601 |
+
{
|
1602 |
+
self::__triggerError(sprintf("S3::getDistributionInvalidationList(): [%s] %s",
|
1603 |
+
"CloudFront functionality requires SSL"), __FILE__, __LINE__);
|
1604 |
+
return false;
|
1605 |
+
}
|
1606 |
+
|
1607 |
+
$useSSL = self::$useSSL;
|
1608 |
+
self::$useSSL = true; // CloudFront requires SSL
|
1609 |
+
$rest = new S3Request('GET', '', '2010-11-01/distribution/'.$distributionId.'/invalidation', 'cloudfront.amazonaws.com');
|
1610 |
+
$rest = self::__getCloudFrontResponse($rest);
|
1611 |
+
self::$useSSL = $useSSL;
|
1612 |
+
|
1613 |
+
if ($rest->error === false && $rest->code !== 200)
|
1614 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
1615 |
+
if ($rest->error !== false)
|
1616 |
+
{
|
1617 |
+
trigger_error(sprintf("S3::getDistributionInvalidationList('{$distributionId}'): [%s]",
|
1618 |
+
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
1619 |
+
return false;
|
1620 |
+
}
|
1621 |
+
elseif ($rest->body instanceof SimpleXMLElement && isset($rest->body->InvalidationSummary))
|
1622 |
+
{
|
1623 |
+
$list = array();
|
1624 |
+
foreach ($rest->body->InvalidationSummary as $summary)
|
1625 |
+
$list[(string)$summary->Id] = (string)$summary->Status;
|
1626 |
+
|
1627 |
+
return $list;
|
1628 |
+
}
|
1629 |
+
return array();
|
1630 |
+
}
|
1631 |
+
|
1632 |
+
|
1633 |
+
/**
|
1634 |
+
* Get a DistributionConfig DOMDocument
|
1635 |
+
*
|
1636 |
+
* http://docs.amazonwebservices.com/AmazonCloudFront/latest/APIReference/index.html?PutConfig.html
|
1637 |
+
*
|
1638 |
+
* @internal Used to create XML in createDistribution() and updateDistribution()
|
1639 |
+
* @param string $bucket S3 Origin bucket
|
1640 |
+
* @param boolean $enabled Enabled (true/false)
|
1641 |
+
* @param string $comment Comment to append
|
1642 |
+
* @param string $callerReference Caller reference
|
1643 |
+
* @param array $cnames Array of CNAME aliases
|
1644 |
+
* @param string $defaultRootObject Default root object
|
1645 |
+
* @param string $originAccessIdentity Origin access identity
|
1646 |
+
* @param array $trustedSigners Array of trusted signers
|
1647 |
+
* @return string
|
1648 |
+
*/
|
1649 |
+
private static function __getCloudFrontDistributionConfigXML($bucket, $enabled, $comment, $callerReference = '0', $cnames = array(), $defaultRootObject = null, $originAccessIdentity = null, $trustedSigners = array())
|
1650 |
+
{
|
1651 |
+
$dom = new DOMDocument('1.0', 'UTF-8');
|
1652 |
+
$dom->formatOutput = true;
|
1653 |
+
$distributionConfig = $dom->createElement('DistributionConfig');
|
1654 |
+
$distributionConfig->setAttribute('xmlns', 'http://cloudfront.amazonaws.com/doc/2010-11-01/');
|
1655 |
+
|
1656 |
+
$origin = $dom->createElement('S3Origin');
|
1657 |
+
$origin->appendChild($dom->createElement('DNSName', $bucket));
|
1658 |
+
if ($originAccessIdentity !== null) $origin->appendChild($dom->createElement('OriginAccessIdentity', $originAccessIdentity));
|
1659 |
+
$distributionConfig->appendChild($origin);
|
1660 |
+
|
1661 |
+
if ($defaultRootObject !== null) $distributionConfig->appendChild($dom->createElement('DefaultRootObject', $defaultRootObject));
|
1662 |
+
|
1663 |
+
$distributionConfig->appendChild($dom->createElement('CallerReference', $callerReference));
|
1664 |
+
foreach ($cnames as $cname)
|
1665 |
+
$distributionConfig->appendChild($dom->createElement('CNAME', $cname));
|
1666 |
+
if ($comment !== '') $distributionConfig->appendChild($dom->createElement('Comment', $comment));
|
1667 |
+
$distributionConfig->appendChild($dom->createElement('Enabled', $enabled ? 'true' : 'false'));
|
1668 |
+
|
1669 |
+
$trusted = $dom->createElement('TrustedSigners');
|
1670 |
+
foreach ($trustedSigners as $id => $type)
|
1671 |
+
$trusted->appendChild($id !== '' ? $dom->createElement($type, $id) : $dom->createElement($type));
|
1672 |
+
$distributionConfig->appendChild($trusted);
|
1673 |
+
|
1674 |
+
$dom->appendChild($distributionConfig);
|
1675 |
+
//var_dump($dom->saveXML());
|
1676 |
+
return $dom->saveXML();
|
1677 |
+
}
|
1678 |
+
|
1679 |
+
|
1680 |
+
/**
|
1681 |
+
* Parse a CloudFront distribution config
|
1682 |
+
*
|
1683 |
+
* See http://docs.amazonwebservices.com/AmazonCloudFront/latest/APIReference/index.html?GetDistribution.html
|
1684 |
+
*
|
1685 |
+
* @internal Used to parse the CloudFront DistributionConfig node to an array
|
1686 |
+
* @param object &$node DOMNode
|
1687 |
+
* @return array
|
1688 |
+
*/
|
1689 |
+
private static function __parseCloudFrontDistributionConfig(&$node)
|
1690 |
+
{
|
1691 |
+
if (isset($node->DistributionConfig))
|
1692 |
+
return self::__parseCloudFrontDistributionConfig($node->DistributionConfig);
|
1693 |
+
|
1694 |
+
$dist = array();
|
1695 |
+
if (isset($node->Id, $node->Status, $node->LastModifiedTime, $node->DomainName))
|
1696 |
+
{
|
1697 |
+
$dist['id'] = (string)$node->Id;
|
1698 |
+
$dist['status'] = (string)$node->Status;
|
1699 |
+
$dist['time'] = strtotime((string)$node->LastModifiedTime);
|
1700 |
+
$dist['domain'] = (string)$node->DomainName;
|
1701 |
+
}
|
1702 |
+
|
1703 |
+
if (isset($node->CallerReference))
|
1704 |
+
$dist['callerReference'] = (string)$node->CallerReference;
|
1705 |
+
|
1706 |
+
if (isset($node->Enabled))
|
1707 |
+
$dist['enabled'] = (string)$node->Enabled == 'true' ? true : false;
|
1708 |
+
|
1709 |
+
if (isset($node->S3Origin))
|
1710 |
+
{
|
1711 |
+
if (isset($node->S3Origin->DNSName))
|
1712 |
+
$dist['origin'] = (string)$node->S3Origin->DNSName;
|
1713 |
+
|
1714 |
+
$dist['originAccessIdentity'] = isset($node->S3Origin->OriginAccessIdentity) ?
|
1715 |
+
(string)$node->S3Origin->OriginAccessIdentity : null;
|
1716 |
+
}
|
1717 |
+
|
1718 |
+
$dist['defaultRootObject'] = isset($node->DefaultRootObject) ? (string)$node->DefaultRootObject : null;
|
1719 |
+
|
1720 |
+
$dist['cnames'] = array();
|
1721 |
+
if (isset($node->CNAME))
|
1722 |
+
foreach ($node->CNAME as $cname)
|
1723 |
+
$dist['cnames'][(string)$cname] = (string)$cname;
|
1724 |
+
|
1725 |
+
$dist['trustedSigners'] = array();
|
1726 |
+
if (isset($node->TrustedSigners))
|
1727 |
+
foreach ($node->TrustedSigners as $signer)
|
1728 |
+
{
|
1729 |
+
if (isset($signer->Self))
|
1730 |
+
$dist['trustedSigners'][''] = 'Self';
|
1731 |
+
elseif (isset($signer->KeyPairId))
|
1732 |
+
$dist['trustedSigners'][(string)$signer->KeyPairId] = 'KeyPairId';
|
1733 |
+
elseif (isset($signer->AwsAccountNumber))
|
1734 |
+
$dist['trustedSigners'][(string)$signer->AwsAccountNumber] = 'AwsAccountNumber';
|
1735 |
+
}
|
1736 |
+
|
1737 |
+
$dist['comment'] = isset($node->Comment) ? (string)$node->Comment : null;
|
1738 |
+
return $dist;
|
1739 |
+
}
|
1740 |
+
|
1741 |
+
|
1742 |
+
/**
|
1743 |
+
* Grab CloudFront response
|
1744 |
+
*
|
1745 |
+
* @internal Used to parse the CloudFront S3Request::getResponse() output
|
1746 |
+
* @param object &$rest S3Request instance
|
1747 |
+
* @return object
|
1748 |
+
*/
|
1749 |
+
private static function __getCloudFrontResponse(&$rest)
|
1750 |
+
{
|
1751 |
+
$rest->getResponse();
|
1752 |
+
if ($rest->response->error === false && isset($rest->response->body) &&
|
1753 |
+
is_string($rest->response->body) && substr($rest->response->body, 0, 5) == '<?xml')
|
1754 |
+
{
|
1755 |
+
$rest->response->body = simplexml_load_string($rest->response->body);
|
1756 |
+
// Grab CloudFront errors
|
1757 |
+
if (isset($rest->response->body->Error, $rest->response->body->Error->Code,
|
1758 |
+
$rest->response->body->Error->Message))
|
1759 |
+
{
|
1760 |
+
$rest->response->error = array(
|
1761 |
+
'code' => (string)$rest->response->body->Error->Code,
|
1762 |
+
'message' => (string)$rest->response->body->Error->Message
|
1763 |
+
);
|
1764 |
+
unset($rest->response->body);
|
1765 |
+
}
|
1766 |
+
}
|
1767 |
+
return $rest->response;
|
1768 |
+
}
|
1769 |
+
|
1770 |
+
|
1771 |
+
/**
|
1772 |
+
* Get MIME type for file
|
1773 |
+
*
|
1774 |
+
* @internal Used to get mime types
|
1775 |
+
* @param string &$file File path
|
1776 |
+
* @return string
|
1777 |
+
*/
|
1778 |
+
public static function __getMimeType(&$file)
|
1779 |
+
{
|
1780 |
+
$type = false;
|
1781 |
+
// Fileinfo documentation says fileinfo_open() will use the
|
1782 |
+
// MAGIC env var for the magic file
|
1783 |
+
if (extension_loaded('fileinfo') && isset($_ENV['MAGIC']) &&
|
1784 |
+
($finfo = finfo_open(FILEINFO_MIME, $_ENV['MAGIC'])) !== false)
|
1785 |
+
{
|
1786 |
+
if (($type = finfo_file($finfo, $file)) !== false)
|
1787 |
+
{
|
1788 |
+
// Remove the charset and grab the last content-type
|
1789 |
+
$type = explode(' ', str_replace('; charset=', ';charset=', $type));
|
1790 |
+
$type = array_pop($type);
|
1791 |
+
$type = explode(';', $type);
|
1792 |
+
$type = trim(array_shift($type));
|
1793 |
+
}
|
1794 |
+
finfo_close($finfo);
|
1795 |
+
|
1796 |
+
// If anyone is still using mime_content_type()
|
1797 |
+
} elseif (function_exists('mime_content_type'))
|
1798 |
+
$type = trim(mime_content_type($file));
|
1799 |
+
|
1800 |
+
if ($type !== false && strlen($type) > 0) return $type;
|
1801 |
+
|
1802 |
+
// Otherwise do it the old fashioned way
|
1803 |
+
static $exts = array(
|
1804 |
+
'jpg' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png',
|
1805 |
+
'tif' => 'image/tiff', 'tiff' => 'image/tiff', 'ico' => 'image/x-icon',
|
1806 |
+
'swf' => 'application/x-shockwave-flash', 'pdf' => 'application/pdf',
|
1807 |
+
'zip' => 'application/zip', 'gz' => 'application/x-gzip',
|
1808 |
+
'tar' => 'application/x-tar', 'bz' => 'application/x-bzip',
|
1809 |
+
'bz2' => 'application/x-bzip2', 'txt' => 'text/plain',
|
1810 |
+
'asc' => 'text/plain', 'htm' => 'text/html', 'html' => 'text/html',
|
1811 |
+
'css' => 'text/css', 'js' => 'text/javascript',
|
1812 |
+
'xml' => 'text/xml', 'xsl' => 'application/xsl+xml',
|
1813 |
+
'ogg' => 'application/ogg', 'mp3' => 'audio/mpeg', 'wav' => 'audio/x-wav',
|
1814 |
+
'avi' => 'video/x-msvideo', 'mpg' => 'video/mpeg', 'mpeg' => 'video/mpeg',
|
1815 |
+
'mov' => 'video/quicktime', 'flv' => 'video/x-flv', 'php' => 'text/x-php'
|
1816 |
+
);
|
1817 |
+
$ext = strtolower(pathInfo($file, PATHINFO_EXTENSION));
|
1818 |
+
return isset($exts[$ext]) ? $exts[$ext] : 'application/octet-stream';
|
1819 |
+
}
|
1820 |
+
|
1821 |
+
|
1822 |
+
/**
|
1823 |
+
* Generate the auth string: "AWS AccessKey:Signature"
|
1824 |
+
*
|
1825 |
+
* @internal Used by S3Request::getResponse()
|
1826 |
+
* @param string $string String to sign
|
1827 |
+
* @return string
|
1828 |
+
*/
|
1829 |
+
public static function __getSignature($string)
|
1830 |
+
{
|
1831 |
+
return 'AWS '.self::$__accessKey.':'.self::__getHash($string);
|
1832 |
+
}
|
1833 |
+
|
1834 |
+
|
1835 |
+
/**
|
1836 |
+
* Creates a HMAC-SHA1 hash
|
1837 |
+
*
|
1838 |
+
* This uses the hash extension if loaded
|
1839 |
+
*
|
1840 |
+
* @internal Used by __getSignature()
|
1841 |
+
* @param string $string String to sign
|
1842 |
+
* @return string
|
1843 |
+
*/
|
1844 |
+
private static function __getHash($string)
|
1845 |
+
{
|
1846 |
+
return base64_encode(extension_loaded('hash') ?
|
1847 |
+
hash_hmac('sha1', $string, self::$__secretKey, true) : pack('H*', sha1(
|
1848 |
+
(str_pad(self::$__secretKey, 64, chr(0x00)) ^ (str_repeat(chr(0x5c), 64))) .
|
1849 |
+
pack('H*', sha1((str_pad(self::$__secretKey, 64, chr(0x00)) ^
|
1850 |
+
(str_repeat(chr(0x36), 64))) . $string)))));
|
1851 |
+
}
|
1852 |
+
|
1853 |
+
}
|
1854 |
+
|
1855 |
+
final class S3Request
|
1856 |
+
{
|
1857 |
+
private $endpoint, $verb, $bucket, $uri, $resource = '', $parameters = array(),
|
1858 |
+
$amzHeaders = array(), $headers = array(
|
1859 |
+
'Host' => '', 'Date' => '', 'Content-MD5' => '', 'Content-Type' => ''
|
1860 |
+
);
|
1861 |
+
public $fp = false, $size = 0, $data = false, $response;
|
1862 |
+
|
1863 |
+
|
1864 |
+
/**
|
1865 |
+
* Constructor
|
1866 |
+
*
|
1867 |
+
* @param string $verb Verb
|
1868 |
+
* @param string $bucket Bucket name
|
1869 |
+
* @param string $uri Object URI
|
1870 |
+
* @return mixed
|
1871 |
+
*/
|
1872 |
+
function __construct($verb, $bucket = '', $uri = '', $endpoint = 's3.amazonaws.com')
|
1873 |
+
{
|
1874 |
+
$this->endpoint = $endpoint;
|
1875 |
+
$this->verb = $verb;
|
1876 |
+
$this->bucket = $bucket;
|
1877 |
+
$this->uri = $uri !== '' ? '/'.str_replace('%2F', '/', rawurlencode($uri)) : '/';
|
1878 |
+
|
1879 |
+
//if ($this->bucket !== '')
|
1880 |
+
// $this->resource = '/'.$this->bucket.$this->uri;
|
1881 |
+
//else
|
1882 |
+
// $this->resource = $this->uri;
|
1883 |
+
|
1884 |
+
if ($this->bucket !== '')
|
1885 |
+
{
|
1886 |
+
if ($this->__dnsBucketName($this->bucket))
|
1887 |
+
{
|
1888 |
+
$this->headers['Host'] = $this->bucket.'.'.$this->endpoint;
|
1889 |
+
$this->resource = '/'.$this->bucket.$this->uri;
|
1890 |
+
}
|
1891 |
+
else
|
1892 |
+
{
|
1893 |
+
$this->headers['Host'] = $this->endpoint;
|
1894 |
+
$this->uri = $this->uri;
|
1895 |
+
if ($this->bucket !== '') $this->uri = '/'.$this->bucket.$this->uri;
|
1896 |
+
$this->bucket = '';
|
1897 |
+
$this->resource = $this->uri;
|
1898 |
+
}
|
1899 |
+
}
|
1900 |
+
else
|
1901 |
+
{
|
1902 |
+
$this->headers['Host'] = $this->endpoint;
|
1903 |
+
$this->resource = $this->uri;
|
1904 |
+
}
|
1905 |
+
|
1906 |
+
|
1907 |
+
$this->headers['Date'] = gmdate('D, d M Y H:i:s T');
|
1908 |
+
$this->response = new STDClass;
|
1909 |
+
$this->response->error = false;
|
1910 |
+
}
|
1911 |
+
|
1912 |
+
|
1913 |
+
/**
|
1914 |
+
* Set request parameter
|
1915 |
+
*
|
1916 |
+
* @param string $key Key
|
1917 |
+
* @param string $value Value
|
1918 |
+
* @return void
|
1919 |
+
*/
|
1920 |
+
public function setParameter($key, $value)
|
1921 |
+
{
|
1922 |
+
$this->parameters[$key] = $value;
|
1923 |
+
}
|
1924 |
+
|
1925 |
+
|
1926 |
+
/**
|
1927 |
+
* Set request header
|
1928 |
+
*
|
1929 |
+
* @param string $key Key
|
1930 |
+
* @param string $value Value
|
1931 |
+
* @return void
|
1932 |
+
*/
|
1933 |
+
public function setHeader($key, $value)
|
1934 |
+
{
|
1935 |
+
$this->headers[$key] = $value;
|
1936 |
+
}
|
1937 |
+
|
1938 |
+
|
1939 |
+
/**
|
1940 |
+
* Set x-amz-meta-* header
|
1941 |
+
*
|
1942 |
+
* @param string $key Key
|
1943 |
+
* @param string $value Value
|
1944 |
+
* @return void
|
1945 |
+
*/
|
1946 |
+
public function setAmzHeader($key, $value)
|
1947 |
+
{
|
1948 |
+
$this->amzHeaders[$key] = $value;
|
1949 |
+
}
|
1950 |
+
|
1951 |
+
|
1952 |
+
/**
|
1953 |
+
* Get the S3 response
|
1954 |
+
*
|
1955 |
+
* @return object | false
|
1956 |
+
*/
|
1957 |
+
public function getResponse()
|
1958 |
+
{
|
1959 |
+
$query = '';
|
1960 |
+
if (sizeof($this->parameters) > 0)
|
1961 |
+
{
|
1962 |
+
$query = substr($this->uri, -1) !== '?' ? '?' : '&';
|
1963 |
+
foreach ($this->parameters as $var => $value)
|
1964 |
+
if ($value == null || $value == '') $query .= $var.'&';
|
1965 |
+
else $query .= $var.'='.rawurlencode($value).'&';
|
1966 |
+
$query = substr($query, 0, -1);
|
1967 |
+
$this->uri .= $query;
|
1968 |
+
|
1969 |
+
if (array_key_exists('acl', $this->parameters) ||
|
1970 |
+
array_key_exists('location', $this->parameters) ||
|
1971 |
+
array_key_exists('torrent', $this->parameters) ||
|
1972 |
+
array_key_exists('logging', $this->parameters) ||
|
1973 |
+
array_key_exists('partNumber', $this->parameters) ||
|
1974 |
+
array_key_exists('uploads', $this->parameters) ||
|
1975 |
+
array_key_exists('uploadId', $this->parameters))
|
1976 |
+
$this->resource .= $query;
|
1977 |
+
}
|
1978 |
+
$url = (S3::$useSSL ? 'https://' : 'http://') . ($this->headers['Host'] !== '' ? $this->headers['Host'] : $this->endpoint) . $this->uri;
|
1979 |
+
|
1980 |
+
//var_dump('bucket: ' . $this->bucket, 'uri: ' . $this->uri, 'resource: ' . $this->resource, 'url: ' . $url);
|
1981 |
+
|
1982 |
+
// Basic setup
|
1983 |
+
$curl = curl_init();
|
1984 |
+
curl_setopt($curl, CURLOPT_USERAGENT, 'S3/php');
|
1985 |
+
|
1986 |
+
if (S3::$useSSL)
|
1987 |
+
{
|
1988 |
+
// SSL Validation can now be optional for those with broken OpenSSL installations
|
1989 |
+
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, S3::$useSSLValidation ? 1 : 0);
|
1990 |
+
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, S3::$useSSLValidation ? 1 : 0);
|
1991 |
+
|
1992 |
+
if (S3::$sslKey !== null) curl_setopt($curl, CURLOPT_SSLKEY, S3::$sslKey);
|
1993 |
+
if (S3::$sslCert !== null) curl_setopt($curl, CURLOPT_SSLCERT, S3::$sslCert);
|
1994 |
+
if (S3::$sslCACert !== null) curl_setopt($curl, CURLOPT_CAINFO, S3::$sslCACert);
|
1995 |
+
}
|
1996 |
+
|
1997 |
+
curl_setopt($curl, CURLOPT_URL, $url);
|
1998 |
+
|
1999 |
+
if (S3::$proxy != null && isset(S3::$proxy['host']))
|
2000 |
+
{
|
2001 |
+
curl_setopt($curl, CURLOPT_PROXY, S3::$proxy['host']);
|
2002 |
+
curl_setopt($curl, CURLOPT_PROXYTYPE, S3::$proxy['type']);
|
2003 |
+
if (isset(S3::$proxy['user'], S3::$proxy['pass']) && S3::$proxy['user'] != null && S3::$proxy['pass'] != null)
|
2004 |
+
curl_setopt($curl, CURLOPT_PROXYUSERPWD, sprintf('%s:%s', S3::$proxy['user'], S3::$proxy['pass']));
|
2005 |
+
}
|
2006 |
+
|
2007 |
+
// Headers
|
2008 |
+
$headers = array(); $amz = array();
|
2009 |
+
foreach ($this->amzHeaders as $header => $value)
|
2010 |
+
if (strlen($value) > 0) $headers[] = $header.': '.$value;
|
2011 |
+
foreach ($this->headers as $header => $value)
|
2012 |
+
if (strlen($value) > 0) $headers[] = $header.': '.$value;
|
2013 |
+
|
2014 |
+
// Collect AMZ headers for signature
|
2015 |
+
foreach ($this->amzHeaders as $header => $value)
|
2016 |
+
if (strlen($value) > 0) $amz[] = strtolower($header).':'.$value;
|
2017 |
+
|
2018 |
+
// AMZ headers must be sorted
|
2019 |
+
if (sizeof($amz) > 0)
|
2020 |
+
{
|
2021 |
+
//sort($amz);
|
2022 |
+
usort($amz, array(&$this, '__sortMetaHeadersCmp'));
|
2023 |
+
$amz = "\n".implode("\n", $amz);
|
2024 |
+
} else $amz = '';
|
2025 |
+
|
2026 |
+
if (S3::hasAuth())
|
2027 |
+
{
|
2028 |
+
// Authorization string (CloudFront stringToSign should only contain a date)
|
2029 |
+
if ($this->headers['Host'] == 'cloudfront.amazonaws.com')
|
2030 |
+
$headers[] = 'Authorization: ' . S3::__getSignature($this->headers['Date']);
|
2031 |
+
else
|
2032 |
+
{
|
2033 |
+
$headers[] = 'Authorization: ' . S3::__getSignature(
|
2034 |
+
$this->verb."\n".
|
2035 |
+
$this->headers['Content-MD5']."\n".
|
2036 |
+
$this->headers['Content-Type']."\n".
|
2037 |
+
$this->headers['Date'].$amz."\n".
|
2038 |
+
$this->resource
|
2039 |
+
);
|
2040 |
+
}
|
2041 |
+
}
|
2042 |
+
|
2043 |
+
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
2044 |
+
curl_setopt($curl, CURLOPT_HEADER, false);
|
2045 |
+
curl_setopt($curl, CURLOPT_RETURNTRANSFER, false);
|
2046 |
+
curl_setopt($curl, CURLOPT_WRITEFUNCTION, array(&$this, '__responseWriteCallback'));
|
2047 |
+
curl_setopt($curl, CURLOPT_HEADERFUNCTION, array(&$this, '__responseHeaderCallback'));
|
2048 |
+
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
|
2049 |
+
|
2050 |
+
// Request types
|
2051 |
+
switch ($this->verb)
|
2052 |
+
{
|
2053 |
+
case 'GET': break;
|
2054 |
+
case 'PUT': case 'POST':
|
2055 |
+
if ($this->fp !== false)
|
2056 |
+
{
|
2057 |
+
curl_setopt($curl, CURLOPT_PUT, true);
|
2058 |
+
curl_setopt($curl, CURLOPT_INFILE, $this->fp);
|
2059 |
+
if ($this->size >= 0)
|
2060 |
+
curl_setopt($curl, CURLOPT_INFILESIZE, $this->size);
|
2061 |
+
}
|
2062 |
+
elseif ($this->data !== false)
|
2063 |
+
{
|
2064 |
+
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
|
2065 |
+
curl_setopt($curl, CURLOPT_POSTFIELDS, $this->data);
|
2066 |
+
}
|
2067 |
+
else
|
2068 |
+
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
|
2069 |
+
break;
|
2070 |
+
case 'HEAD':
|
2071 |
+
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'HEAD');
|
2072 |
+
curl_setopt($curl, CURLOPT_NOBODY, true);
|
2073 |
+
break;
|
2074 |
+
case 'DELETE':
|
2075 |
+
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
|
2076 |
+
break;
|
2077 |
+
default: break;
|
2078 |
+
}
|
2079 |
+
|
2080 |
+
// Execute, grab errors
|
2081 |
+
if (curl_exec($curl))
|
2082 |
+
$this->response->code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
2083 |
+
else
|
2084 |
+
$this->response->error = array(
|
2085 |
+
'code' => curl_errno($curl),
|
2086 |
+
'message' => curl_error($curl),
|
2087 |
+
'resource' => $this->resource
|
2088 |
+
);
|
2089 |
+
|
2090 |
+
@curl_close($curl);
|
2091 |
+
|
2092 |
+
// Parse body into XML
|
2093 |
+
if ($this->response->error === false && isset($this->response->headers['type']) &&
|
2094 |
+
$this->response->headers['type'] == 'application/xml' && isset($this->response->body))
|
2095 |
+
{
|
2096 |
+
$this->response->body = simplexml_load_string($this->response->body);
|
2097 |
+
|
2098 |
+
// Grab S3 errors
|
2099 |
+
if (!in_array($this->response->code, array(200, 204, 206)) &&
|
2100 |
+
isset($this->response->body->Code, $this->response->body->Message))
|
2101 |
+
{
|
2102 |
+
$this->response->error = array(
|
2103 |
+
'code' => (string)$this->response->body->Code,
|
2104 |
+
'message' => (string)$this->response->body->Message
|
2105 |
+
);
|
2106 |
+
if (isset($this->response->body->Resource))
|
2107 |
+
$this->response->error['resource'] = (string)$this->response->body->Resource;
|
2108 |
+
unset($this->response->body);
|
2109 |
+
}
|
2110 |
+
}
|
2111 |
+
|
2112 |
+
// Clean up file resources
|
2113 |
+
if ($this->fp !== false && is_resource($this->fp)) fclose($this->fp);
|
2114 |
+
|
2115 |
+
return $this->response;
|
2116 |
+
}
|
2117 |
+
|
2118 |
+
/**
|
2119 |
+
* Sort compare for meta headers
|
2120 |
+
*
|
2121 |
+
* @internal Used to sort x-amz meta headers
|
2122 |
+
* @param string $a String A
|
2123 |
+
* @param string $b String B
|
2124 |
+
* @return integer
|
2125 |
+
*/
|
2126 |
+
private function __sortMetaHeadersCmp($a, $b)
|
2127 |
+
{
|
2128 |
+
$lenA = strpos($a, ':');
|
2129 |
+
$lenB = strpos($b, ':');
|
2130 |
+
$minLen = min($lenA, $lenB);
|
2131 |
+
$ncmp = strncmp($a, $b, $minLen);
|
2132 |
+
if ($lenA == $lenB) return $ncmp;
|
2133 |
+
if (0 == $ncmp) return $lenA < $lenB ? -1 : 1;
|
2134 |
+
return $ncmp;
|
2135 |
+
}
|
2136 |
+
|
2137 |
+
/**
|
2138 |
+
* CURL write callback
|
2139 |
+
*
|
2140 |
+
* @param resource &$curl CURL resource
|
2141 |
+
* @param string &$data Data
|
2142 |
+
* @return integer
|
2143 |
+
*/
|
2144 |
+
private function __responseWriteCallback(&$curl, &$data)
|
2145 |
+
{
|
2146 |
+
if (in_array($this->response->code, array(200, 206)) && $this->fp !== false)
|
2147 |
+
return fwrite($this->fp, $data);
|
2148 |
+
else
|
2149 |
+
$this->response->body .= $data;
|
2150 |
+
return strlen($data);
|
2151 |
+
}
|
2152 |
+
|
2153 |
+
|
2154 |
+
/**
|
2155 |
+
* Check DNS conformity
|
2156 |
+
*
|
2157 |
+
* @param string $bucket Bucket name
|
2158 |
+
* @return boolean
|
2159 |
+
*/
|
2160 |
+
private function __dnsBucketName($bucket)
|
2161 |
+
{
|
2162 |
+
if (strlen($bucket) > 63 || !preg_match("/[^a-z0-9\.-]/", $bucket)) return false;
|
2163 |
+
if (strstr($bucket, '-.') !== false) return false;
|
2164 |
+
if (strstr($bucket, '..') !== false) return false;
|
2165 |
+
if (!preg_match("/^[0-9a-z]/", $bucket)) return false;
|
2166 |
+
if (!preg_match("/[0-9a-z]$/", $bucket)) return false;
|
2167 |
+
return true;
|
2168 |
+
}
|
2169 |
+
|
2170 |
+
|
2171 |
+
/**
|
2172 |
+
* CURL header callback
|
2173 |
+
*
|
2174 |
+
* @param resource &$curl CURL resource
|
2175 |
+
* @param string &$data Data
|
2176 |
+
* @return integer
|
2177 |
+
*/
|
2178 |
+
private function __responseHeaderCallback(&$curl, &$data)
|
2179 |
+
{
|
2180 |
+
if (($strlen = strlen($data)) <= 2) return $strlen;
|
2181 |
+
if (substr($data, 0, 4) == 'HTTP')
|
2182 |
+
$this->response->code = (int)substr($data, 9, 3);
|
2183 |
+
else
|
2184 |
+
{
|
2185 |
+
$data = trim($data);
|
2186 |
+
if (strpos($data, ': ') === false) return $strlen;
|
2187 |
+
list($header, $value) = explode(': ', $data, 2);
|
2188 |
+
if ($header == 'Last-Modified')
|
2189 |
+
$this->response->headers['time'] = strtotime($value);
|
2190 |
+
elseif ($header == 'Content-Length')
|
2191 |
+
$this->response->headers['size'] = (int)$value;
|
2192 |
+
elseif ($header == 'Content-Type')
|
2193 |
+
$this->response->headers['type'] = $value;
|
2194 |
+
elseif ($header == 'ETag')
|
2195 |
+
$this->response->headers['hash'] = $value{0} == '"' ? substr($value, 1, -1) : $value;
|
2196 |
+
elseif (preg_match('/^x-amz-meta-.*$/', $header))
|
2197 |
+
$this->response->headers[$header] = $value;
|
2198 |
+
}
|
2199 |
+
return $strlen;
|
2200 |
+
}
|
2201 |
+
|
2202 |
+
}
|
2203 |
+
|
2204 |
+
class S3Exception extends Exception {
|
2205 |
+
function __construct($message, $file, $line, $code = 0)
|
2206 |
+
{
|
2207 |
+
parent::__construct($message, $code);
|
2208 |
+
$this->file = $file;
|
2209 |
+
$this->line = $line;
|
2210 |
+
}
|
2211 |
+
}
|
trunk/includes/ajax.js
ADDED
File without changes
|
trunk/includes/class-gdocs.php
ADDED
@@ -0,0 +1,630 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Originally contained: GDocs class
|
4 |
+
// Contains: UpdraftPlus_GDocs class (new methods added - could not extend, as too much was private)
|
5 |
+
|
6 |
+
// The following copyright notice is reproduced exactly as found in the "Backup" plugin (http://wordpress.org/extend/plugins/backup)
|
7 |
+
// It applies to the code apart from the methods we added (get_content_link, download_data)
|
8 |
+
|
9 |
+
/*
|
10 |
+
Copyright 2012 Sorin Iclanzan (email : sorin@hel.io)
|
11 |
+
|
12 |
+
This file is part of Backup.
|
13 |
+
|
14 |
+
Backup is free software: you can redistribute it and/or modify
|
15 |
+
it under the terms of the GNU General Public License as published by
|
16 |
+
the Free Software Foundation, either version 3 of the License, or
|
17 |
+
(at your option) any later version.
|
18 |
+
|
19 |
+
Backup is distributed in the hope that it will be useful,
|
20 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
21 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
22 |
+
GNU General Public License for more details.
|
23 |
+
|
24 |
+
You should have received a copy of the GNU General Public License
|
25 |
+
along with Backup. If not, see http://www.gnu.org/licenses/gpl.html.
|
26 |
+
*/
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Google Docs class
|
30 |
+
*
|
31 |
+
* Implements communication with Google Docs via the Google Documents List v3 API.
|
32 |
+
*
|
33 |
+
* Currently uploading, resuming and deleting resources is implemented as well as retrieving quotas.
|
34 |
+
*
|
35 |
+
* @uses WP_Error for storing error messages.
|
36 |
+
*/
|
37 |
+
class UpdraftPlus_GDocs {
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Stores the API version.
|
41 |
+
*
|
42 |
+
* @var string
|
43 |
+
* @access private
|
44 |
+
*/
|
45 |
+
private $gdata_version;
|
46 |
+
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Stores the base URL for the API requests.
|
50 |
+
*
|
51 |
+
* @var string
|
52 |
+
* @access private
|
53 |
+
*/
|
54 |
+
private $base_url;
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Stores the URL to the metadata feed.
|
58 |
+
* @var string
|
59 |
+
*/
|
60 |
+
private $metadata_url;
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Stores the token needed to access the API.
|
64 |
+
* @var string
|
65 |
+
* @access private
|
66 |
+
*/
|
67 |
+
private $token;
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Stores feeds to avoid requesting them again for successive use.
|
71 |
+
*
|
72 |
+
* @var array
|
73 |
+
* @access private
|
74 |
+
*/
|
75 |
+
private $cache = array();
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Files are uploadded in chunks of this size in bytes.
|
79 |
+
*
|
80 |
+
* @var integer
|
81 |
+
* @access private
|
82 |
+
*/
|
83 |
+
private $chunk_size;
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Stores whether or not to verify host SSL certificate.
|
87 |
+
*
|
88 |
+
* @var boolean
|
89 |
+
* @access private
|
90 |
+
*/
|
91 |
+
private $ssl_verify;
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Stores the number of seconds to wait for a response before timing out.
|
95 |
+
*
|
96 |
+
* @var integer
|
97 |
+
* @access private
|
98 |
+
*/
|
99 |
+
private $request_timeout;
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Stores the MIME type of the file that is uploading
|
103 |
+
*
|
104 |
+
* @var string
|
105 |
+
* @access private
|
106 |
+
*/
|
107 |
+
private $upload_file_type;
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Stores info about the file being uploaded.
|
111 |
+
*
|
112 |
+
* @var array
|
113 |
+
* @access private
|
114 |
+
*/
|
115 |
+
private $file;
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Stores the number of seconds the upload process is allowed to run
|
119 |
+
*
|
120 |
+
* @var integer
|
121 |
+
* @access private
|
122 |
+
*/
|
123 |
+
private $time_limit;
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Stores a timer for upload processes
|
127 |
+
*
|
128 |
+
* @var array
|
129 |
+
*/
|
130 |
+
private $timer;
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Constructor - Sets the access token.
|
134 |
+
*
|
135 |
+
* @param string $token Access token
|
136 |
+
*/
|
137 |
+
function __construct( $token ) {
|
138 |
+
$this->token = $token;
|
139 |
+
$this->gdata_version = '3.0';
|
140 |
+
$this->base_url = 'https://docs.google.com/feeds/default/private/full/';
|
141 |
+
$this->metadata_url = 'https://docs.google.com/feeds/metadata/default';
|
142 |
+
$this->chunk_size = 524288; // 512 KiB
|
143 |
+
$this->max_resume_attempts = 5;
|
144 |
+
$this->request_timeout = 5;
|
145 |
+
$this->ssl_verify = true;
|
146 |
+
$this->timer = array(
|
147 |
+
'start' => 0,
|
148 |
+
'stop' => 0,
|
149 |
+
'delta' => 0,
|
150 |
+
'cycle' => 0
|
151 |
+
);
|
152 |
+
$this->time_limit = @ini_get( 'max_execution_time' );
|
153 |
+
if ( ! $this->time_limit && '0' !== $this->time_limit )
|
154 |
+
$this->time_limit = 30; // default php max exec time
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Sets an option.
|
159 |
+
*
|
160 |
+
* @access public
|
161 |
+
* @param string $option The option to set.
|
162 |
+
* @param mixed $value The value to set the option to.
|
163 |
+
*/
|
164 |
+
public function set_option( $option, $value ) {
|
165 |
+
switch ( $option ) {
|
166 |
+
case 'chunk_size':
|
167 |
+
if ( floatval($value) >= 0.5 ) {
|
168 |
+
$this->chunk_size = floatval($value) * 1024 * 1024; // Transform from MiB to bytes
|
169 |
+
return true;
|
170 |
+
}
|
171 |
+
break;
|
172 |
+
case 'ssl_verify':
|
173 |
+
$this->ssl_verify = ( bool ) $value;
|
174 |
+
return true;
|
175 |
+
case 'request_timeout':
|
176 |
+
if ( intval( $value ) > 0 ) {
|
177 |
+
$this->request_timeout = intval( $value );
|
178 |
+
return true;
|
179 |
+
}
|
180 |
+
break;
|
181 |
+
case 'max_resume_attempts':
|
182 |
+
$this->max_resume_attempts = intval($value);
|
183 |
+
return true;
|
184 |
+
}
|
185 |
+
return false;
|
186 |
+
}
|
187 |
+
|
188 |
+
/**
|
189 |
+
* Gets an option.
|
190 |
+
*
|
191 |
+
* @access public
|
192 |
+
* @param string $option The option to get.
|
193 |
+
*/
|
194 |
+
public function get_option( $option ) {
|
195 |
+
switch ( $option ) {
|
196 |
+
case 'chunk_size':
|
197 |
+
return $this->chunk_size;
|
198 |
+
case 'ssl_verify':
|
199 |
+
return $this->ssl_verify;
|
200 |
+
case 'request_timeout':
|
201 |
+
return $this->request_timeout;
|
202 |
+
case 'max_resume_attempts':
|
203 |
+
return $this->max_resume_attempts;
|
204 |
+
}
|
205 |
+
return false;
|
206 |
+
}
|
207 |
+
|
208 |
+
/**
|
209 |
+
* This function makes all the requests to the API.
|
210 |
+
*
|
211 |
+
* @uses wp_remote_request
|
212 |
+
* @access private
|
213 |
+
* @param string $url The URL where the request is sent.
|
214 |
+
* @param string $method The HTTP request method, defaults to 'GET'.
|
215 |
+
* @param array $headers Headers to be sent.
|
216 |
+
* @param string $body The body of the request.
|
217 |
+
* @return mixed Returns an array containing the response on success or an instance of WP_Error on failure.
|
218 |
+
*/
|
219 |
+
private function request( $url, $method = 'GET', $headers = array(), $body = NULL ) {
|
220 |
+
$args = array(
|
221 |
+
'method' => $method,
|
222 |
+
'timeout' => $this->request_timeout,
|
223 |
+
'httpversion' => '1.1',
|
224 |
+
'redirection' => 0,
|
225 |
+
'sslverify' => $this->ssl_verify,
|
226 |
+
'headers' => array(
|
227 |
+
'Authorization' => 'Bearer ' . $this->token,
|
228 |
+
'GData-Version' => $this->gdata_version
|
229 |
+
)
|
230 |
+
);
|
231 |
+
if ( ! empty( $headers ) )
|
232 |
+
$args['headers'] = array_merge( $args['headers'], $headers );
|
233 |
+
if ( ! empty( $body ) )
|
234 |
+
$args['body'] = $body;
|
235 |
+
|
236 |
+
return wp_remote_request( $url, $args );
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Returns the feed from a URL.
|
241 |
+
*
|
242 |
+
* @access public
|
243 |
+
* @param string $url The feed URL.
|
244 |
+
* @return mixed Returns the feed as an instance of SimpleXMLElement on success or an instance of WP_Error on failure.
|
245 |
+
*/
|
246 |
+
public function get_feed( $url ) {
|
247 |
+
if ( ! isset( $this->cache[$url] ) ) {
|
248 |
+
$result = $this->cache_feed( $url );
|
249 |
+
if ( is_wp_error( $result ) )
|
250 |
+
return $result;
|
251 |
+
}
|
252 |
+
|
253 |
+
return $this->cache[$url];
|
254 |
+
}
|
255 |
+
|
256 |
+
/**
|
257 |
+
* Requests a feed and adds it to cache.
|
258 |
+
*
|
259 |
+
* @access private
|
260 |
+
* @param string $url The feed URL.
|
261 |
+
* @return mixed Returns TRUE on success or an instance of WP_Error on failure.
|
262 |
+
*/
|
263 |
+
private function cache_feed( $url ) {
|
264 |
+
$result = $this->request( $url );
|
265 |
+
|
266 |
+
if ( is_wp_error( $result ) )
|
267 |
+
return $result;
|
268 |
+
|
269 |
+
if ( $result['response']['code'] == '200' ) {
|
270 |
+
$feed = @simplexml_load_string( $result['body'] );
|
271 |
+
if ( $feed === false )
|
272 |
+
return new WP_Error( 'invalid_data', "Could not create SimpleXMLElement from '" . $result['body'] . "'." );
|
273 |
+
|
274 |
+
$this->cache[$url] = $feed;
|
275 |
+
return true;
|
276 |
+
}
|
277 |
+
return new WP_Error( 'bad_response', "Received response code '" . $result['response']['code'] . " " . $result['response']['message'] . "' while trying to get '" . $url . "'. Response body: " . $result['body'] );
|
278 |
+
|
279 |
+
}
|
280 |
+
|
281 |
+
/**
|
282 |
+
* Deletes a resource from Google Docs.
|
283 |
+
*
|
284 |
+
* @access public
|
285 |
+
* @param string $id Gdata Id of the resource to be deleted.
|
286 |
+
* @return mixed Returns TRUE on success, an instance of WP_Error on failure.
|
287 |
+
*/
|
288 |
+
public function delete_resource( $id ) {
|
289 |
+
$headers = array( 'If-Match' => '*' );
|
290 |
+
|
291 |
+
$result = $this->request( $this->base_url . $id . '?delete=true', 'DELETE', $headers );
|
292 |
+
if ( is_wp_error( $result ) )
|
293 |
+
return $result;
|
294 |
+
|
295 |
+
if ( $result['response']['code'] == '200' )
|
296 |
+
return true;
|
297 |
+
return new WP_Error( 'bad_response', "Received response code '" . $result['response']['code'] . " " . $result['response']['message'] . "' while trying to delete resource '" . $id . "'. The resource might not have been deleted." );
|
298 |
+
}
|
299 |
+
|
300 |
+
/**
|
301 |
+
* Get the resumable-create-media link needed to upload files.
|
302 |
+
*
|
303 |
+
* @access private
|
304 |
+
* @param string $parent The Id of the folder where the upload is to be made. Default is empty string.
|
305 |
+
* @return mixed Returns a link on success, instance of WP_Error on failure.
|
306 |
+
*/
|
307 |
+
private function get_resumable_create_media_link( $parent = '' ) {
|
308 |
+
$url = $this->base_url;
|
309 |
+
if ( $parent )
|
310 |
+
$url .= $parent;
|
311 |
+
|
312 |
+
$feed = $this->get_feed( $url );
|
313 |
+
|
314 |
+
if ( is_wp_error( $feed ) )
|
315 |
+
return $feed;
|
316 |
+
|
317 |
+
foreach ( $feed->link as $link )
|
318 |
+
if ( $link['rel'] == 'http://schemas.google.com/g/2005#resumable-create-media' )
|
319 |
+
return ( string ) $link['href'];
|
320 |
+
return new WP_Error( 'not_found', "The 'resumable_create_media_link' was not found in feed." );
|
321 |
+
}
|
322 |
+
|
323 |
+
/**
|
324 |
+
* Get used quota in bytes.
|
325 |
+
*
|
326 |
+
* @access public
|
327 |
+
* @return mixed Returns the number of bytes used in Google Docs on success or an instance of WP_Error on failure.
|
328 |
+
*/
|
329 |
+
public function get_quota_used() {
|
330 |
+
$feed = $this->get_feed( $this->metadata_url );
|
331 |
+
if ( is_wp_error( $feed ) )
|
332 |
+
return $feed;
|
333 |
+
return ( string ) $feed->children( "http://schemas.google.com/g/2005" )->quotaBytesUsed;
|
334 |
+
}
|
335 |
+
|
336 |
+
/**
|
337 |
+
* Get total quota in bytes.
|
338 |
+
*
|
339 |
+
* @access public
|
340 |
+
* @return string|WP_Error Returns the total quota in bytes in Google Docs on success or an instance of WP_Error on failure.
|
341 |
+
*/
|
342 |
+
public function get_quota_total() {
|
343 |
+
$feed = $this->get_feed( $this->metadata_url );
|
344 |
+
if ( is_wp_error( $feed ) )
|
345 |
+
return $feed;
|
346 |
+
return ( string ) $feed->children( "http://schemas.google.com/g/2005" )->quotaBytesTotal;
|
347 |
+
}
|
348 |
+
|
349 |
+
/**
|
350 |
+
* Function to prepare a file to be uploaded to Google Docs.
|
351 |
+
*
|
352 |
+
* The function requests a URI for uploading and prepends a new element in the resume_list array.
|
353 |
+
*
|
354 |
+
* @uses wp_check_filetype
|
355 |
+
* @access public
|
356 |
+
*
|
357 |
+
* @param string $file Path to the file that is to be uploaded.
|
358 |
+
* @param string $title Title to be given to the file.
|
359 |
+
* @param string $parent ID of the folder in which to upload the file.
|
360 |
+
* @param string $type MIME type of the file to be uploaded. The function tries to identify the type if it is omitted.
|
361 |
+
* @return mixed Returns the URI where to upload on success, an instance of WP_Error on failure.
|
362 |
+
*/
|
363 |
+
public function prepare_upload( $file, $title, $parent = '', $type = '' ) {
|
364 |
+
if ( ! @is_readable( $file ) )
|
365 |
+
return new WP_Error( 'not_file', "The path '" . $file . "' does not point to a readable file." );
|
366 |
+
|
367 |
+
// If a mime type wasn't passed try to guess it from the extension based on the WordPress allowed mime types
|
368 |
+
if ( empty( $type ) ) {
|
369 |
+
$check = wp_check_filetype( $file );
|
370 |
+
$this->upload_file_type = $type = $check['type'];
|
371 |
+
}
|
372 |
+
|
373 |
+
$size = filesize( $file );
|
374 |
+
|
375 |
+
$body = '<?xml version=\'1.0\' encoding=\'UTF-8\'?><entry xmlns="http://www.w3.org/2005/Atom" xmlns:docs="http://schemas.google.com/docs/2007"><category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/docs/2007#file"/><title>' . $title . '</title></entry>';
|
376 |
+
|
377 |
+
$headers = array(
|
378 |
+
'Content-Type' => 'application/atom+xml',
|
379 |
+
'X-Upload-Content-Type' => $type,
|
380 |
+
'X-Upload-Content-Length' => (string) $size
|
381 |
+
);
|
382 |
+
|
383 |
+
$url = $this->get_resumable_create_media_link( $parent );
|
384 |
+
|
385 |
+
if ( is_wp_error( $url ) )
|
386 |
+
return $url;
|
387 |
+
|
388 |
+
$url .= '?convert=false'; // needed to upload a file
|
389 |
+
|
390 |
+
$result = $this->request( $url, 'POST', $headers, $body );
|
391 |
+
|
392 |
+
if ( is_wp_error( $result ) )
|
393 |
+
return $result;
|
394 |
+
|
395 |
+
if ( $result['response']['code'] != '200' )
|
396 |
+
return new WP_Error( 'bad_response', "Received response code '" . $result['response']['code'] . " " . $result['response']['message'] . "' while trying to get '" . $url . "'." );
|
397 |
+
|
398 |
+
$this->file = array(
|
399 |
+
'path' => $file,
|
400 |
+
'size' => $size,
|
401 |
+
'location' => $result['headers']['location'],
|
402 |
+
'pointer' => 0
|
403 |
+
);
|
404 |
+
|
405 |
+
// Open file for reading.
|
406 |
+
if ( !$this->file['handle'] = fopen( $file, "rb" ) )
|
407 |
+
return new WP_Error( 'open_error', "Could not open file '" . $file . "' for reading." );
|
408 |
+
|
409 |
+
// Start timer
|
410 |
+
$this->timer['start'] = microtime( true );
|
411 |
+
|
412 |
+
return $result['headers']['location'];
|
413 |
+
}
|
414 |
+
|
415 |
+
|
416 |
+
/**
|
417 |
+
* Resume an upload.
|
418 |
+
*
|
419 |
+
* @access public
|
420 |
+
* @param string $file Path to the file which needs to be uploaded
|
421 |
+
* @param string $location URI where to upload the file
|
422 |
+
* @return mixed Returns the next location URI on success, an instance of WP_Error on failure.
|
423 |
+
*/
|
424 |
+
public function resume_upload( $file, $location ) {
|
425 |
+
|
426 |
+
if ( ! @is_readable( $file ) )
|
427 |
+
return new WP_Error( 'not_file', "The path '" . $this->resume_list[$id]['path'] . "' does not point to a readable file. Upload has been canceled." );
|
428 |
+
|
429 |
+
$size = filesize( $file );
|
430 |
+
|
431 |
+
$headers = array( 'Content-Range' => 'bytes */' . $size );
|
432 |
+
$result = $this->request( $location, 'PUT', $headers );
|
433 |
+
if( is_wp_error( $result ) )
|
434 |
+
return $result;
|
435 |
+
|
436 |
+
if ( '308' != $result['response']['code'] ) {
|
437 |
+
if ( '201' == $result['response']['code'] ) {
|
438 |
+
$feed = @simplexml_load_string( $result['body'] );
|
439 |
+
if ( $feed === false )
|
440 |
+
return new WP_Error( 'invalid_data', "Could not create SimpleXMLElement from '" . $result['body'] . "'." );
|
441 |
+
$this->file['id'] = substr( ( string ) $feed->children( "http://schemas.google.com/g/2005" )->resourceId, 5 );
|
442 |
+
return true;
|
443 |
+
}
|
444 |
+
return new WP_Error( 'bad_response', "Received response code '" . $result['response']['code'] . " " . $result['response']['message'] . "' while trying to resume the upload of file '" . $file . "'." );
|
445 |
+
}
|
446 |
+
if( isset( $result['headers']['location'] ) )
|
447 |
+
$location = $result['headers']['location'];
|
448 |
+
$pointer = $this->pointer( $result['headers']['range'] );
|
449 |
+
|
450 |
+
$this->file = array(
|
451 |
+
'path' => $file,
|
452 |
+
'size' => $size,
|
453 |
+
'location' => $location,
|
454 |
+
'pointer' => $pointer
|
455 |
+
);
|
456 |
+
|
457 |
+
// Open file for reading.
|
458 |
+
if ( !$this->file['handle'] = fopen( $file, "rb" ) )
|
459 |
+
return new WP_Error( 'open_error', "Could not open file '" . $file . "' for reading." );
|
460 |
+
|
461 |
+
// Start timer
|
462 |
+
$this->timer['start'] = microtime( true );
|
463 |
+
|
464 |
+
return $location;
|
465 |
+
}
|
466 |
+
|
467 |
+
/**
|
468 |
+
* Work out where the file pointer should be from the range header.
|
469 |
+
*
|
470 |
+
* @access private
|
471 |
+
* @param string $range The range HTTP response header.
|
472 |
+
* @return integer Returns the number of bytes that have been uploaded.
|
473 |
+
*/
|
474 |
+
private function pointer( $range ) {
|
475 |
+
return intval(substr( $range, strpos( $range, '-' ) + 1 )) + 1;
|
476 |
+
}
|
477 |
+
|
478 |
+
/**
|
479 |
+
* Uploads a chunk of the file being uploaded.
|
480 |
+
*
|
481 |
+
* @access public
|
482 |
+
* @return mixed Returns TRUE if the chunk was uploaded successfully;
|
483 |
+
* returns Google Docs resource ID if the file upload finished;
|
484 |
+
* returns an instance of WP_Error on failure.
|
485 |
+
*/
|
486 |
+
public function upload_chunk() {
|
487 |
+
if ( !isset( $this->file['handle'] ) )
|
488 |
+
return new WP_Error( "no_upload", "There is no file being uploaded." );
|
489 |
+
|
490 |
+
$cycle_start = microtime( true );
|
491 |
+
fseek( $this->file['handle'], $this->file['pointer'] );
|
492 |
+
$chunk = @fread( $this->file['handle'], $this->chunk_size );
|
493 |
+
if ( false === $chunk ) {
|
494 |
+
$is_file = (is_file($this->file['path'])) ? 1 : 0;
|
495 |
+
$is_readable = (is_readable($this->file['path'])) ? 1 : 0;
|
496 |
+
return new WP_Error( 'read_error', "Failed to read from file (path: ".$this->file['path'].", size: ".$this->file['size'].", pointer: ".$this->file['pointer'].", is_file: $is_file, is_readable: $is_readable)");
|
497 |
+
}
|
498 |
+
|
499 |
+
$chunk_size = strlen( $chunk );
|
500 |
+
$bytes = 'bytes ' . (string)$this->file['pointer'] . '-' . (string)($this->file['pointer'] + $chunk_size - 1) . '/' . (string)$this->file['size'];
|
501 |
+
|
502 |
+
$headers = array( 'Content-Range' => $bytes );
|
503 |
+
|
504 |
+
$result = $this->request( $this->file['location'], 'PUT', $headers, $chunk );
|
505 |
+
|
506 |
+
if ( !is_wp_error( $result ) )
|
507 |
+
if ( '308' == $result['response']['code'] ) {
|
508 |
+
if ( isset( $result['headers']['range'] ) )
|
509 |
+
$this->file['pointer'] = $this->pointer( $result['headers']['range'] );
|
510 |
+
else
|
511 |
+
$this->file['pointer'] += $chunk_size;
|
512 |
+
|
513 |
+
if ( isset( $result['headers']['location'] ) )
|
514 |
+
$this->file['location'] = $result['headers']['location'];
|
515 |
+
|
516 |
+
if ( $this->timer['cycle'] )
|
517 |
+
$this->timer['cycle'] = ( microtime( true ) - $cycle_start + $this->timer['cycle'] ) / 2;
|
518 |
+
else
|
519 |
+
$this->timer['cycle'] = microtime(true) - $cycle_start;
|
520 |
+
|
521 |
+
return $this->file['location'];
|
522 |
+
}
|
523 |
+
elseif ( '201' == $result['response']['code'] ) {
|
524 |
+
fclose( $this->file['handle'] );
|
525 |
+
|
526 |
+
// Stop timer
|
527 |
+
$this->timer['stop'] = microtime(true);
|
528 |
+
$this->timer['delta'] = $this->timer['stop'] - $this->timer['start'];
|
529 |
+
|
530 |
+
if ( $this->timer['cycle'] )
|
531 |
+
$this->timer['cycle'] = ( microtime( true ) - $cycle_start + $this->timer['cycle'] ) / 2;
|
532 |
+
else
|
533 |
+
$this->timer['cycle'] = microtime(true) - $cycle_start;
|
534 |
+
|
535 |
+
$this->file['pointer'] = $this->file['size'];
|
536 |
+
|
537 |
+
$feed = @simplexml_load_string( $result['body'] );
|
538 |
+
if ( $feed === false )
|
539 |
+
return new WP_Error( 'invalid_data', "Could not create SimpleXMLElement from '" . $result['body'] . "'." );
|
540 |
+
$this->file['id'] = substr( ( string ) $feed->children( "http://schemas.google.com/g/2005" )->resourceId, 5 );
|
541 |
+
return true;
|
542 |
+
}
|
543 |
+
|
544 |
+
// If we got to this point it means the upload wasn't successful.
|
545 |
+
fclose( $this->file['handle'] );
|
546 |
+
if ( is_wp_error( $result ) )
|
547 |
+
return $result;
|
548 |
+
return new WP_Error( 'bad_response', "Received response code '" . $result['response']['code'] . " " . $result['response']['message'] . "' while trying to upload a file chunk." );
|
549 |
+
}
|
550 |
+
|
551 |
+
/**
|
552 |
+
* Get the resource ID of the most recent uploaded file.
|
553 |
+
*
|
554 |
+
* @access public
|
555 |
+
* @return string The ID of the uploaded file or an empty string.
|
556 |
+
*/
|
557 |
+
public function get_file_id() {
|
558 |
+
if ( isset( $this->file['id'] ) )
|
559 |
+
return $this->file['id'];
|
560 |
+
return '';
|
561 |
+
}
|
562 |
+
|
563 |
+
/**
|
564 |
+
* Get the upload speed recorded on the last upload performed.
|
565 |
+
*
|
566 |
+
* @access public
|
567 |
+
* @return integer Returns the upload speed in bytes/second or 0.
|
568 |
+
*/
|
569 |
+
public function get_upload_speed() {
|
570 |
+
if ( $this->timer['cycle'] > 0 )
|
571 |
+
if ( $this->file['size'] < $this->chunk_size )
|
572 |
+
return $this->file['size'] / $this->timer['cycle'];
|
573 |
+
else
|
574 |
+
return $this->chunk_size / $this->timer['cycle'];
|
575 |
+
return 0;
|
576 |
+
}
|
577 |
+
|
578 |
+
/**
|
579 |
+
* Get the percentage of the file uploaded.
|
580 |
+
*
|
581 |
+
* @return float Returns a percentage on success, 0 on failure.
|
582 |
+
*/
|
583 |
+
public function get_upload_percentage() {
|
584 |
+
if ( isset( $this->file['path'] ) )
|
585 |
+
return $this->file['pointer'] * 100 / $this->file['size'];
|
586 |
+
return 0;
|
587 |
+
}
|
588 |
+
|
589 |
+
/**
|
590 |
+
* Returns the time taken for an upload to complete.
|
591 |
+
*
|
592 |
+
* @access public
|
593 |
+
* @return float Returns the number of seconds the last upload took to complete, 0 if there has been no completed upload.
|
594 |
+
*/
|
595 |
+
public function time_taken() {
|
596 |
+
return $this->timer['delta'];
|
597 |
+
}
|
598 |
+
|
599 |
+
public function get_content_link( $id, $title ) {
|
600 |
+
|
601 |
+
$feed = $this->get_feed($this->base_url . $id);
|
602 |
+
|
603 |
+
if ( is_wp_error( $feed ) )
|
604 |
+
return $feed;
|
605 |
+
|
606 |
+
if ( $feed->title != $title )
|
607 |
+
return new WP_Error( 'bad_response', "Unexpected response");
|
608 |
+
|
609 |
+
$att = $feed->content->attributes();
|
610 |
+
return $att['src'];
|
611 |
+
|
612 |
+
}
|
613 |
+
|
614 |
+
public function download_data( $link, $saveas ) {
|
615 |
+
|
616 |
+
$result = $this->request( $link );
|
617 |
+
|
618 |
+
if ( is_wp_error( $result ) )
|
619 |
+
return $result;
|
620 |
+
|
621 |
+
if ( $result['response']['code'] != '200' )
|
622 |
+
return new WP_Error( 'bad_response', "Received response code '" . $result['response']['code'] . " " . $result['response']['message'] . "' while trying to get '" . $url . "'." );
|
623 |
+
|
624 |
+
file_put_contents($saveas, $result['body']);
|
625 |
+
|
626 |
+
}
|
627 |
+
|
628 |
+
|
629 |
+
|
630 |
+
}
|
trunk/includes/ftp.class.php
ADDED
@@ -0,0 +1,194 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/* from http://www.solutionbot.com/2009/01/02/php-ftp-class/ */
|
3 |
+
class ftp_wrapper
|
4 |
+
{
|
5 |
+
private $conn_id;
|
6 |
+
private $host;
|
7 |
+
private $username;
|
8 |
+
private $password;
|
9 |
+
private $port;
|
10 |
+
public $timeout = 90;
|
11 |
+
public $passive = false;
|
12 |
+
public $ssl = false;
|
13 |
+
public $system_type = '';
|
14 |
+
|
15 |
+
public function __construct($host, $username, $password, $port = 21)
|
16 |
+
{
|
17 |
+
$this->host = $host;
|
18 |
+
$this->username = $username;
|
19 |
+
$this->password = $password;
|
20 |
+
$this->port = $port;
|
21 |
+
}
|
22 |
+
|
23 |
+
public function connect()
|
24 |
+
{
|
25 |
+
if ($this->ssl == false)
|
26 |
+
{
|
27 |
+
$this->conn_id = ftp_connect($this->host, $this->port);
|
28 |
+
}
|
29 |
+
else
|
30 |
+
{
|
31 |
+
if (function_exists('ftp_ssl_connect'))
|
32 |
+
{
|
33 |
+
$this->conn_id = ftp_ssl_connect($this->host, $this->port);
|
34 |
+
}
|
35 |
+
else
|
36 |
+
{
|
37 |
+
return false;
|
38 |
+
}
|
39 |
+
}
|
40 |
+
|
41 |
+
if ($this->conn_id === false) return false;
|
42 |
+
|
43 |
+
$result = ftp_login($this->conn_id, $this->username, $this->password);
|
44 |
+
|
45 |
+
if ($result == true)
|
46 |
+
{
|
47 |
+
ftp_set_option($this->conn_id, FTP_TIMEOUT_SEC, $this->timeout);
|
48 |
+
|
49 |
+
if ($this->passive == true)
|
50 |
+
{
|
51 |
+
ftp_pasv($this->conn_id, true);
|
52 |
+
}
|
53 |
+
else
|
54 |
+
{
|
55 |
+
ftp_pasv($this->conn_id, false);
|
56 |
+
}
|
57 |
+
|
58 |
+
$this->system_type = ftp_systype($this->conn_id);
|
59 |
+
|
60 |
+
return true;
|
61 |
+
}
|
62 |
+
else
|
63 |
+
{
|
64 |
+
return false;
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
public function put($local_file_path, $remote_file_path, $mode = FTP_ASCII)
|
69 |
+
{
|
70 |
+
if (ftp_put($this->conn_id, $remote_file_path, $local_file_path, $mode))
|
71 |
+
{
|
72 |
+
return true;
|
73 |
+
}
|
74 |
+
else
|
75 |
+
{
|
76 |
+
return false;
|
77 |
+
}
|
78 |
+
}
|
79 |
+
|
80 |
+
public function get($local_file_path, $remote_file_path, $mode = FTP_ASCII)
|
81 |
+
{
|
82 |
+
if (ftp_get($this->conn_id, $local_file_path, $remote_file_path, $mode))
|
83 |
+
{
|
84 |
+
return true;
|
85 |
+
}
|
86 |
+
else
|
87 |
+
{
|
88 |
+
return false;
|
89 |
+
}
|
90 |
+
}
|
91 |
+
|
92 |
+
public function chmod($permissions, $remote_filename)
|
93 |
+
{
|
94 |
+
if ($this->is_octal($permissions))
|
95 |
+
{
|
96 |
+
$result = ftp_chmod($this->conn_id, $permissions, $remote_filename);
|
97 |
+
if ($result)
|
98 |
+
{
|
99 |
+
return true;
|
100 |
+
}
|
101 |
+
else
|
102 |
+
{
|
103 |
+
return false;
|
104 |
+
}
|
105 |
+
}
|
106 |
+
else
|
107 |
+
{
|
108 |
+
throw new Exception('$permissions must be an octal number');
|
109 |
+
}
|
110 |
+
}
|
111 |
+
|
112 |
+
public function chdir($directory)
|
113 |
+
{
|
114 |
+
ftp_chdir($this->conn_id, $directory);
|
115 |
+
}
|
116 |
+
|
117 |
+
public function delete($remote_file_path)
|
118 |
+
{
|
119 |
+
if (ftp_delete($this->conn_id, $remote_file_path))
|
120 |
+
{
|
121 |
+
return true;
|
122 |
+
}
|
123 |
+
else
|
124 |
+
{
|
125 |
+
return false;
|
126 |
+
}
|
127 |
+
}
|
128 |
+
|
129 |
+
public function make_dir($directory)
|
130 |
+
{
|
131 |
+
if (ftp_mkdir($this->conn_id, $directory))
|
132 |
+
{
|
133 |
+
return true;
|
134 |
+
}
|
135 |
+
else
|
136 |
+
{
|
137 |
+
return false;
|
138 |
+
}
|
139 |
+
}
|
140 |
+
|
141 |
+
public function rename($old_name, $new_name)
|
142 |
+
{
|
143 |
+
if (ftp_rename($this->conn_id, $old_name, $new_name))
|
144 |
+
{
|
145 |
+
return true;
|
146 |
+
}
|
147 |
+
else
|
148 |
+
{
|
149 |
+
return false;
|
150 |
+
}
|
151 |
+
}
|
152 |
+
|
153 |
+
public function remove_dir($directory)
|
154 |
+
{
|
155 |
+
if (ftp_rmdir($this->conn_id, $directory))
|
156 |
+
{
|
157 |
+
return true;
|
158 |
+
}
|
159 |
+
else
|
160 |
+
{
|
161 |
+
return false;
|
162 |
+
}
|
163 |
+
}
|
164 |
+
|
165 |
+
public function dir_list($directory)
|
166 |
+
{
|
167 |
+
$contents = ftp_nlist($this->conn_id, $directory);
|
168 |
+
return $contents;
|
169 |
+
}
|
170 |
+
|
171 |
+
public function cdup()
|
172 |
+
{
|
173 |
+
ftp_cdup($this->conn_id);
|
174 |
+
}
|
175 |
+
|
176 |
+
public function current_dir()
|
177 |
+
{
|
178 |
+
return ftp_pwd($this->conn_id);
|
179 |
+
}
|
180 |
+
|
181 |
+
private function is_octal($i)
|
182 |
+
{
|
183 |
+
return decoct(octdec($i)) == $i;
|
184 |
+
}
|
185 |
+
|
186 |
+
public function __destruct()
|
187 |
+
{
|
188 |
+
if ($this->conn_id)
|
189 |
+
{
|
190 |
+
ftp_close($this->conn_id);
|
191 |
+
}
|
192 |
+
}
|
193 |
+
}
|
194 |
+
?>
|
trunk/includes/updraft-restorer.php
ADDED
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Updraft_Restorer extends WP_Upgrader {
|
3 |
+
|
4 |
+
function backup_strings() {
|
5 |
+
$this->strings['no_package'] = __('Backup file not available.');
|
6 |
+
$this->strings['unpack_package'] = __('Unpacking backup...');
|
7 |
+
$this->strings['moving_old'] = __('Moving old directory out of the way...');
|
8 |
+
$this->strings['moving_backup'] = __('Moving unpackaged backup in place...');
|
9 |
+
$this->strings['cleaning_up'] = __('Cleaning up detritus...');
|
10 |
+
$this->strings['old_move_failed'] = __('Could not move old dir out of the way.');
|
11 |
+
$this->strings['new_move_failed'] = __('Could not move new dir into place. Check your wp-content/upgrade folder.');
|
12 |
+
$this->strings['delete_failed'] = __('Failed to delete working directory after restoring.');
|
13 |
+
}
|
14 |
+
|
15 |
+
function restore_backup($backup_file, $type) {
|
16 |
+
|
17 |
+
if ($type != 'plugins' && $type != 'themes' && $type != 'others' && $type != 'uploads') continue;
|
18 |
+
|
19 |
+
global $wp_filesystem;
|
20 |
+
$this->init();
|
21 |
+
$this->backup_strings();
|
22 |
+
|
23 |
+
$res = $this->fs_connect(array(ABSPATH, WP_CONTENT_DIR) );
|
24 |
+
if(!$res) exit;
|
25 |
+
|
26 |
+
$wp_dir = trailingslashit($wp_filesystem->abspath());
|
27 |
+
|
28 |
+
$download = $this->download_package( $backup_file );
|
29 |
+
if ( is_wp_error($download) )
|
30 |
+
return $download;
|
31 |
+
|
32 |
+
$delete = (UpdraftPlus_Options::get_updraft_option('updraft_delete_local')) ? true : false;
|
33 |
+
|
34 |
+
$working_dir = $this->unpack_package($download , $delete);
|
35 |
+
if (is_wp_error($working_dir)) return $working_dir;
|
36 |
+
|
37 |
+
if ($type == "others" ) {
|
38 |
+
|
39 |
+
// In this special case, the backup contents are not in a folder, so it is not simply a case of moving the folder around, but rather looping over all that we find
|
40 |
+
|
41 |
+
$upgrade_files = $wp_filesystem->dirlist($working_dir);
|
42 |
+
if ( !empty($upgrade_files) ) {
|
43 |
+
foreach ( $upgrade_files as $filestruc ) {
|
44 |
+
$file = $filestruc['name'];
|
45 |
+
# Sanity check (should not be possible as these were excluded at backup time)
|
46 |
+
if ($file != "plugins" && $file != "themes" && $file != "uploads" && $file != "upgrade") {
|
47 |
+
# First, move the existing one, if necessary (may not be present)
|
48 |
+
if ($wp_filesystem->exists($wp_dir . "wp-content/$file")) {
|
49 |
+
if ( !$wp_filesystem->move($wp_dir . "wp-content/$file", $wp_dir . "wp-content/$file-old", true) ) {
|
50 |
+
return new WP_Error('old_move_failed', $this->strings['old_move_failed']);
|
51 |
+
}
|
52 |
+
}
|
53 |
+
# Now, move in the new one
|
54 |
+
if ( !$wp_filesystem->move($working_dir . "/$file", $wp_dir . "wp-content/$file", true) ) {
|
55 |
+
return new WP_Error('new_move_failed', $this->strings['new_move_failed']);
|
56 |
+
}
|
57 |
+
}
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
61 |
+
} else {
|
62 |
+
|
63 |
+
show_message($this->strings['moving_old']);
|
64 |
+
if ( !$wp_filesystem->move($wp_dir . "wp-content/$type", $wp_dir . "wp-content/$type-old", true) ) {
|
65 |
+
return new WP_Error('old_move_failed', $this->strings['old_move_failed']);
|
66 |
+
}
|
67 |
+
|
68 |
+
show_message($this->strings['moving_backup']);
|
69 |
+
if ( !$wp_filesystem->move($working_dir . "/$type", $wp_dir . "wp-content/$type", true) ) {
|
70 |
+
return new WP_Error('new_move_failed', $this->strings['new_move_failed']);
|
71 |
+
}
|
72 |
+
|
73 |
+
}
|
74 |
+
|
75 |
+
show_message($this->strings['cleaning_up']);
|
76 |
+
if ( !$wp_filesystem->delete($working_dir) ) {
|
77 |
+
return new WP_Error('delete_failed', $this->strings['delete_failed']);
|
78 |
+
}
|
79 |
+
|
80 |
+
|
81 |
+
switch($type) {
|
82 |
+
case 'uploads':
|
83 |
+
@$wp_filesystem->chmod($wp_dir . "wp-content/$type", 0777, true);
|
84 |
+
break;
|
85 |
+
default:
|
86 |
+
@$wp_filesystem->chmod($wp_dir . "wp-content/$type", FS_CHMOD_DIR);
|
87 |
+
}
|
88 |
+
}
|
89 |
+
|
90 |
+
}
|
91 |
+
?>
|
trunk/methods/dropbox.php
ADDED
@@ -0,0 +1,369 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// https://www.dropbox.com/developers/apply?cont=/developers/apps
|
4 |
+
|
5 |
+
class UpdraftPlus_BackupModule_dropbox {
|
6 |
+
|
7 |
+
private $current_file_hash;
|
8 |
+
private $current_file_size;
|
9 |
+
|
10 |
+
function chunked_callback($offset, $uploadid) {
|
11 |
+
global $updraftplus;
|
12 |
+
|
13 |
+
// Update upload ID
|
14 |
+
set_transient('updraf_dbid_'.$this->current_file_hash, $uploadid, UPDRAFT_TRANSTIME);
|
15 |
+
set_transient('updraf_dbof_'.$this->current_file_hash, $offset, UPDRAFT_TRANSTIME);
|
16 |
+
|
17 |
+
if ($this->current_file_size > 0) {
|
18 |
+
$percent = round(100*($offset/$this->current_file_size),1);
|
19 |
+
$updraftplus->record_uploaded_chunk($percent, "($uploadid, $offset)");
|
20 |
+
} else {
|
21 |
+
$updraftplus->log("Dropbox: Chunked Upload: $offset bytes uploaded");
|
22 |
+
}
|
23 |
+
|
24 |
+
}
|
25 |
+
|
26 |
+
function backup($backup_array) {
|
27 |
+
|
28 |
+
global $updraftplus;
|
29 |
+
$updraftplus->log("Dropbox: begin cloud upload");
|
30 |
+
|
31 |
+
if (UpdraftPlus_Options::get_updraft_option('updraft_dropboxtk_request_token', 'xyz') == 'xyz') {
|
32 |
+
$updraftplus->log('You do not appear to be authenticated with Dropbox');
|
33 |
+
$updraftplus->error('You do not appear to be authenticated with Dropbox');
|
34 |
+
return false;
|
35 |
+
}
|
36 |
+
|
37 |
+
try {
|
38 |
+
$dropbox = $this->bootstrap();
|
39 |
+
$dropbox->setChunkSize(524288); // 512Kb
|
40 |
+
} catch (Exception $e) {
|
41 |
+
$updraftplus->log('Dropbox error: '.$e->getMessage().' (line: '.$e->getLine().', file: '.$e->getFile().')');
|
42 |
+
$updraftplus->error('Dropbox error: '.$e->getMessage().' (see log file for more)');
|
43 |
+
return false;
|
44 |
+
}
|
45 |
+
|
46 |
+
$updraft_dir = $updraftplus->backups_dir_location();
|
47 |
+
$dropbox_folder = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dropbox_folder'));
|
48 |
+
|
49 |
+
foreach($backup_array as $file) {
|
50 |
+
$updraftplus->log("Dropbox: Attempt to upload: $file");
|
51 |
+
|
52 |
+
$file_success = 1;
|
53 |
+
|
54 |
+
$hash = md5($file);
|
55 |
+
$this->current_file_hash=$hash;
|
56 |
+
|
57 |
+
$filesize = filesize($updraft_dir.'/'.$file);
|
58 |
+
$this->current_file_size = $filesize;
|
59 |
+
// Into Kb
|
60 |
+
$filesize = $filesize/1024;
|
61 |
+
$microtime = microtime(true);
|
62 |
+
|
63 |
+
if ($upload_id = get_transient('updraf_dbid_'.$hash)) {
|
64 |
+
# Resume
|
65 |
+
$offset = get_transient('updraf_dbof_'.$hash);
|
66 |
+
$updraftplus->log("This is a resumption: $offset bytes had already been uploaded");
|
67 |
+
} else {
|
68 |
+
$offset = 0;
|
69 |
+
$upload_id = null;
|
70 |
+
}
|
71 |
+
|
72 |
+
// I did erroneously have $dropbox_folder as the third parameter in chunkedUpload... this causes a sub-directory to be created
|
73 |
+
// Old-style, single file put: $put = $dropbox->putFile($updraft_dir.'/'.$file, $dropbox_folder.$file);
|
74 |
+
|
75 |
+
$ourself = $this;
|
76 |
+
|
77 |
+
try {
|
78 |
+
$dropbox->chunkedUpload($updraft_dir.'/'.$file, $file, '', true, $offset, $upload_id, array($ourself, 'chunked_callback'));
|
79 |
+
} catch (Exception $e) {
|
80 |
+
$updraftplus->log("Exception: ".$e->getMessage());
|
81 |
+
if (preg_match("/Submitted input out of alignment: got \[(\d+)\] expected \[(\d+)\]/i", $e->getMessage(), $matches)) {
|
82 |
+
// Try the indicated offset
|
83 |
+
$we_tried = $matches[1];
|
84 |
+
$dropbox_wanted = $matches[2];
|
85 |
+
$updraftplus->log("Dropbox alignment error: tried=$we_tried, wanted=$dropbox_wanted; will attempt recovery");
|
86 |
+
try {
|
87 |
+
$dropbox->chunkedUpload($updraft_dir.'/'.$file, $file, '', true, $dropbox_wanted, $upload_id, array($ourself, 'chunked_callback'));
|
88 |
+
} catch (Exception $e) {
|
89 |
+
$updraftplus->log('Dropbox error: '.$e->getMessage().' (line: '.$e->getLine().', file: '.$e->getFile().')');
|
90 |
+
$updraftplus->error("Dropbox error: failed to upload file $file (see full log for more)");
|
91 |
+
$file_success = 0;
|
92 |
+
}
|
93 |
+
} else {
|
94 |
+
$updraftplus->log('Dropbox error: '.$e->getMessage());
|
95 |
+
$updraftplus->error("Dropbox error: failed to upload file $file (see full log for more)");
|
96 |
+
$file_success = 0;
|
97 |
+
}
|
98 |
+
}
|
99 |
+
if ($file_success) {
|
100 |
+
$updraftplus->uploaded_file($file);
|
101 |
+
$microtime_elapsed = microtime(true)-$microtime;
|
102 |
+
$speedps = $filesize/$microtime_elapsed;
|
103 |
+
$speed = sprintf("%.2d",$filesize)." Kb in ".sprintf("%.2d",$microtime_elapsed)."s (".sprintf("%.2d", $speedps)." Kb/s)";
|
104 |
+
$updraftplus->log("Dropbox: File upload success (".$file."): $speed");
|
105 |
+
delete_transient('updraft_duido_'.$hash);
|
106 |
+
delete_transient('updraft_duidi_'.$hash);
|
107 |
+
}
|
108 |
+
|
109 |
+
}
|
110 |
+
|
111 |
+
$updraftplus->prune_retained_backups('dropbox', $this, null);
|
112 |
+
|
113 |
+
}
|
114 |
+
|
115 |
+
function defaults() {
|
116 |
+
return array('Z3Q3ZmkwbnplNHA0Zzlx', 'bTY0bm9iNmY4eWhjODRt');
|
117 |
+
}
|
118 |
+
|
119 |
+
function delete($file) {
|
120 |
+
|
121 |
+
global $updraftplus;
|
122 |
+
$updraftplus->log("Dropbox: request deletion: $file");
|
123 |
+
|
124 |
+
if (UpdraftPlus_Options::get_updraft_option('updraft_dropboxtk_request_token', 'xyz') == 'xyz') {
|
125 |
+
$updraftplus->log('You do not appear to be authenticated with Dropbox');
|
126 |
+
//$updraftplus->error('You do not appear to be authenticated with Dropbox');
|
127 |
+
return false;
|
128 |
+
}
|
129 |
+
|
130 |
+
try {
|
131 |
+
$dropbox = $this->bootstrap();
|
132 |
+
} catch (Exception $e) {
|
133 |
+
$updraftplus->log('Dropbox error: '.$e->getMessage().' (line: '.$e->getLine().', file: '.$e->getFile().')');
|
134 |
+
//$updraftplus->error('Dropbox error: failed to access Dropbox (see log file for more)');
|
135 |
+
return false;
|
136 |
+
}
|
137 |
+
|
138 |
+
$dropbox_folder = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dropbox_folder'));
|
139 |
+
|
140 |
+
$file_success = 1;
|
141 |
+
try {
|
142 |
+
// Apparently $dropbox_folder is not needed
|
143 |
+
$dropbox->delete($file);
|
144 |
+
} catch (Exception $e) {
|
145 |
+
$updraftplus->log('Dropbox error: '.$e->getMessage().' (line: '.$e->getLine().', file: '.$e->getFile().')');
|
146 |
+
// TODO
|
147 |
+
// Add this back October 2013 when removing the block below
|
148 |
+
//$updraftplus->error("Dropbox error: failed to delete file ($file): see log file for more info");
|
149 |
+
$file_success = 0;
|
150 |
+
}
|
151 |
+
if ($file_success) {
|
152 |
+
$updraftplus->log('Dropbox: delete succeeded');
|
153 |
+
} else {
|
154 |
+
$file_success = 1;
|
155 |
+
// We created the file in the wrong place for a while. This code is needed until October 2013, when it can be removed.
|
156 |
+
try {
|
157 |
+
$dropbox->delete($dropbox_folder.'/'.$file);
|
158 |
+
} catch (Exception $e) {
|
159 |
+
$updraftplus->log('Dropbox error: '.$e->getMessage().' (line: '.$e->getLine().', file: '.$e->getFile().')');
|
160 |
+
$file_success = 0;
|
161 |
+
}
|
162 |
+
if ($file_success) $updraftplus->log('Dropbox: delete succeeded (alternative path)');
|
163 |
+
}
|
164 |
+
|
165 |
+
}
|
166 |
+
|
167 |
+
function download($file) {
|
168 |
+
|
169 |
+
global $updraftplus;
|
170 |
+
|
171 |
+
if (UpdraftPlus_Options::get_updraft_option('updraft_dropboxtk_request_token', 'xyz') == 'xyz') {
|
172 |
+
$updraftplus->error('You do not appear to be authenticated with Dropbox');
|
173 |
+
return false;
|
174 |
+
}
|
175 |
+
|
176 |
+
try {
|
177 |
+
$dropbox = $this->bootstrap();
|
178 |
+
} catch (Exception $e) {
|
179 |
+
$updraftplus->log('Dropbox error: '.$e->getMessage().' (line: '.$e->getLine().', file: '.$e->getFile().')');
|
180 |
+
return false;
|
181 |
+
}
|
182 |
+
|
183 |
+
$updraft_dir = $updraftplus->backups_dir_location();
|
184 |
+
$microtime = microtime(true);
|
185 |
+
|
186 |
+
$try_the_other_one = false;
|
187 |
+
try {
|
188 |
+
$get = $dropbox->getFile($file, $updraft_dir.'/'.$file);
|
189 |
+
} catch (Exception $e) {
|
190 |
+
// TODO: Remove this October 2013 (we stored in the wrong place for a while...)
|
191 |
+
$try_the_other_one = true;
|
192 |
+
$possible_error = $e->getMessage();
|
193 |
+
}
|
194 |
+
|
195 |
+
// TODO: Remove this October 2013 (we stored in the wrong place for a while...)
|
196 |
+
if ($try_the_other_one) {
|
197 |
+
$dropbox_folder = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dropbox_folder'));
|
198 |
+
$updraftplus->error('Dropbox error: '.$e);
|
199 |
+
try {
|
200 |
+
$get = $dropbox->getFile($file, $updraft_dir.'/'.$file);
|
201 |
+
} catch (Exception $e) {
|
202 |
+
$updraftplus->error($possible_error);
|
203 |
+
$updraftplus->error($e->getMessage());
|
204 |
+
}
|
205 |
+
}
|
206 |
+
|
207 |
+
}
|
208 |
+
|
209 |
+
public static function config_print() {
|
210 |
+
|
211 |
+
?>
|
212 |
+
<tr class="updraftplusmethod dropbox">
|
213 |
+
<td></td>
|
214 |
+
<td>
|
215 |
+
<img alt="Dropbox logo" src="<?php echo UPDRAFTPLUS_URL.'/images/dropbox-logo.png' ?>">
|
216 |
+
<p><em>Dropbox is a great choice, because UpdraftPlus supports chunked uploads - no matter how big your blog is, UpdraftPlus can upload it a little at a time, and not get thwarted by timeouts.</em></p>
|
217 |
+
</td>
|
218 |
+
</tr>
|
219 |
+
|
220 |
+
<tr class="updraftplusmethod dropbox">
|
221 |
+
<th>Authenticate with Dropbox:</th>
|
222 |
+
<td><p><?php if (UpdraftPlus_Options::get_updraft_option('updraft_dropboxtk_request_token','xyz') != 'xyz') echo "<strong>(You appear to be already authenticated).</strong>"; ?> <a href="?page=updraftplus&action=updraftmethod-dropbox-auth&updraftplus_dropboxauth=doit"><strong>After</strong> you have saved your settings (by clicking "Save Changes" below), then come back here once and click this link to complete authentication with Dropbox.</a>
|
223 |
+
</p>
|
224 |
+
</td>
|
225 |
+
</tr>
|
226 |
+
|
227 |
+
<tr class="updraftplusmethod dropbox">
|
228 |
+
<th></th>
|
229 |
+
<td>
|
230 |
+
<?php
|
231 |
+
// Check requirements.
|
232 |
+
if (!function_exists('mcrypt_encrypt')) {
|
233 |
+
?><p><strong>Warning:</strong> Your web server's PHP installation does not included a required module (MCrypt). Please contact your web hosting provider's support. UpdraftPlus's Dropbox module <strong>requires</strong> MCrypt. Please do not file any support requests; there is no alternative.</p><?php
|
234 |
+
}
|
235 |
+
if (!function_exists("curl_init")) {
|
236 |
+
?><p><strong>Warning:</strong> Your web server's PHP installation does not included a required module (Curl). Please contact your web hosting provider's support. UpdraftPlus's Dropbox module <strong>requires</strong> Curl. Your only options to get this working are 1) Install/enable curl or 2) Hire us or someone else to code additional support options into UpdraftPlus. 3) Wait, possibly forever, for someone else to do this.</p><?php
|
237 |
+
} else {
|
238 |
+
$curl_version = curl_version();
|
239 |
+
$curl_ssl_supported= ($curl_version['features'] & CURL_VERSION_SSL);
|
240 |
+
if (!$curl_ssl_supported) {
|
241 |
+
?><p><strong>Warning:</strong> Your web server's PHP/Curl installation does not support https access. We cannot access Dropbox without this support. Please contact your web hosting provider's support. UpdraftPlus's Dropbox module <strong>requires</strong> Curl+https. Your only options to get this working are 1) Install/enable curl with https or 2) Hire us or someone else to code additional support options into UpdraftPlus. 3) Wait, possibly forever, for someone else to do this.</p><?php
|
242 |
+
}
|
243 |
+
}
|
244 |
+
?>
|
245 |
+
</td>
|
246 |
+
</tr>
|
247 |
+
|
248 |
+
<?php
|
249 |
+
// This setting should never have been used - it is legacy/deprecated
|
250 |
+
?>
|
251 |
+
<input type="hidden" name="updraft_dropbox_folder" value="">
|
252 |
+
|
253 |
+
<?php
|
254 |
+
// Legacy: only show this next setting to old users who had a setting stored
|
255 |
+
if (UpdraftPlus_Options::get_updraft_option('updraft_dropbox_appkey')) {
|
256 |
+
?>
|
257 |
+
|
258 |
+
<tr class="updraftplusmethod dropbox">
|
259 |
+
<th>Your Dropbox App Key:</th>
|
260 |
+
<td><input type="text" autocomplete="off" style="width:332px" id="updraft_dropbox_appkey" name="updraft_dropbox_appkey" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_dropbox_appkey')) ?>" /></td>
|
261 |
+
</tr>
|
262 |
+
<tr class="updraftplusmethod dropbox">
|
263 |
+
<th>Your Dropbox App Secret:</th>
|
264 |
+
<td><input type="text" style="width:332px" id="updraft_dropbox_secret" name="updraft_dropbox_secret" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_dropbox_secret')); ?>" /></td>
|
265 |
+
</tr>
|
266 |
+
|
267 |
+
<?php } ?>
|
268 |
+
|
269 |
+
<!-- <tr class="updraftplusmethod dropbox">
|
270 |
+
<th></th>
|
271 |
+
<td><p><button id="updraft-dropbox-test" type="button" class="button-primary" style="font-size:18px !important">Test Dropbox Settings</button></p></td>
|
272 |
+
</tr>-->
|
273 |
+
<?php
|
274 |
+
}
|
275 |
+
/*
|
276 |
+
function config_print_javascript_onready() {
|
277 |
+
?>
|
278 |
+
jQuery('#updraft-dropbox-test').click(function(){
|
279 |
+
var data = {
|
280 |
+
action: 'updraft_credentials_test',
|
281 |
+
method: 'dropbox',
|
282 |
+
nonce: '<?php echo wp_create_nonce('updraftplus-credentialtest-nonce'); ?>',
|
283 |
+
appkey: jQuery('#updraft_dropbox_appkey').val(),
|
284 |
+
secret: jQuery('#updraft_dropbox_secret').val(),
|
285 |
+
folder: jQuery('#updraft_dropbox_folder').val()
|
286 |
+
};
|
287 |
+
jQuery.post(ajaxurl, data, function(response) {
|
288 |
+
alert('Settings test result: ' + response);
|
289 |
+
});
|
290 |
+
});
|
291 |
+
<?php
|
292 |
+
}*/
|
293 |
+
|
294 |
+
public static function action_auth() {
|
295 |
+
if ( isset( $_GET['oauth_token'] ) ) {
|
296 |
+
self::auth_token();
|
297 |
+
} elseif (isset($_GET['updraftplus_dropboxauth'])) {
|
298 |
+
self::auth_request();
|
299 |
+
}
|
300 |
+
}
|
301 |
+
|
302 |
+
function show_authed_admin_warning() {
|
303 |
+
global $updraftplus;
|
304 |
+
|
305 |
+
$dropbox = self::bootstrap();
|
306 |
+
$accountInfo = $dropbox->accountInfo();
|
307 |
+
|
308 |
+
$message = "<strong>Success</strong>: you have authenticated your Dropbox account";
|
309 |
+
|
310 |
+
if ($accountInfo['code'] != "200") {
|
311 |
+
$message .= " (though part of the returned information was not as expected - your mileage may vary)". $accountInfo['code'];
|
312 |
+
} else {
|
313 |
+
$body = $accountInfo['body'];
|
314 |
+
$message .= ". Your Dropbox account name: ".htmlspecialchars($body->display_name);
|
315 |
+
}
|
316 |
+
$updraftplus->show_admin_warning($message);
|
317 |
+
|
318 |
+
}
|
319 |
+
|
320 |
+
public static function auth_token() {
|
321 |
+
$previous_token = UpdraftPlus_Options::get_updraft_option("updraft_dropboxtk_request_token","xyz");
|
322 |
+
self::bootstrap();
|
323 |
+
$new_token = UpdraftPlus_Options::get_updraft_option("updraft_dropboxtk_request_token","xyz");
|
324 |
+
if ($new_token && $new_token != "xyz") {
|
325 |
+
add_action('admin_notices', array('UpdraftPlus_BackupModule_dropbox', 'show_authed_admin_warning') );
|
326 |
+
}
|
327 |
+
}
|
328 |
+
|
329 |
+
// Acquire single-use authorization code
|
330 |
+
public static function auth_request() {
|
331 |
+
self::bootstrap();
|
332 |
+
}
|
333 |
+
|
334 |
+
// This basically reproduces the relevant bits of bootstrap.php from the SDK
|
335 |
+
function bootstrap() {
|
336 |
+
|
337 |
+
require_once(UPDRAFTPLUS_DIR.'/includes/Dropbox/API.php' );
|
338 |
+
require_once(UPDRAFTPLUS_DIR.'/includes/Dropbox/Exception.php');
|
339 |
+
require_once(UPDRAFTPLUS_DIR.'/includes/Dropbox/API.php');
|
340 |
+
require_once(UPDRAFTPLUS_DIR.'/includes/Dropbox/OAuth/Consumer/ConsumerAbstract.php');
|
341 |
+
require_once(UPDRAFTPLUS_DIR.'/includes/Dropbox/OAuth/Storage/StorageInterface.php');
|
342 |
+
require_once(UPDRAFTPLUS_DIR.'/includes/Dropbox/OAuth/Storage/Encrypter.php');
|
343 |
+
require_once(UPDRAFTPLUS_DIR.'/includes/Dropbox/OAuth/Storage/WordPress.php');
|
344 |
+
require_once(UPDRAFTPLUS_DIR.'/includes/Dropbox/OAuth/Consumer/Curl.php');
|
345 |
+
// require_once(UPDRAFTPLUS_DIR.'/includes/Dropbox/OAuth/Consumer/WordPress.php');
|
346 |
+
|
347 |
+
$key = UpdraftPlus_Options::get_updraft_option('updraft_dropbox_secret');
|
348 |
+
$sec = UpdraftPlus_Options::get_updraft_option('updraft_dropbox_appkey');
|
349 |
+
|
350 |
+
// Set the callback URL
|
351 |
+
$callback = admin_url('options-general.php?page=updraftplus&action=updraftmethod-dropbox-auth');
|
352 |
+
|
353 |
+
// Instantiate the Encrypter and storage objects
|
354 |
+
$encrypter = new Dropbox_Encrypter('ThisOneDoesNotMatterBeyondLength');
|
355 |
+
|
356 |
+
// Instantiate the storage
|
357 |
+
$storage = new Dropbox_WordPress($encrypter, "updraft_dropboxtk_");
|
358 |
+
|
359 |
+
// WordPress consumer does not yet work
|
360 |
+
// $OAuth = new Dropbox_ConsumerWordPress($sec, $key, $storage, $callback);
|
361 |
+
|
362 |
+
// Get the DropBox API access details
|
363 |
+
list($d2, $d1) = self::defaults();
|
364 |
+
if (empty($sec)) { $sec = base64_decode($d1); }; if (empty($key)) { $key = base64_decode($d2); }
|
365 |
+
$OAuth = new Dropbox_Curl($sec, $key, $storage, $callback);
|
366 |
+
return new Dropbox_API($OAuth);
|
367 |
+
}
|
368 |
+
|
369 |
+
}
|
trunk/methods/email.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Files can easily get way too big for this method
|
4 |
+
|
5 |
+
class UpdraftPlus_BackupModule_email {
|
6 |
+
|
7 |
+
function backup($backup_array) {
|
8 |
+
|
9 |
+
global $updraftplus;
|
10 |
+
|
11 |
+
foreach ($backup_array as $type => $file) {
|
12 |
+
$fullpath = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dir')).$file;
|
13 |
+
wp_mail(UpdraftPlus_Options::get_updraft_option('updraft_email'), "WordPress Backup ".date('Y-m-d H:i',$updraftplus->backup_time), "Backup is of the $type. Be wary; email backups may fail because of file size limitations on mail servers.", null, array($fullpath));
|
14 |
+
$updraftplus->uploaded_file($file);
|
15 |
+
}
|
16 |
+
$updraftplus->prune_retained_backups("email", null, null);
|
17 |
+
}
|
18 |
+
|
19 |
+
public static function config_print() {
|
20 |
+
?>
|
21 |
+
<tr class="updraftplusmethod email">
|
22 |
+
<th>Note:</th>
|
23 |
+
<td>The email address entered above will be used. If choosing "E-Mail", then be aware that mail servers tend to have size limits; typically around 10-20Mb; backups larger than any limits will not arrive. If you really need a large backup via email, then you could fund a new feature (to break the backup set into configurable-size pieces) - but the demand has not yet existed for such a feature.</td>
|
24 |
+
</tr>
|
25 |
+
<?php
|
26 |
+
}
|
27 |
+
|
28 |
+
}
|
29 |
+
|
30 |
+
?>
|
trunk/methods/ftp.php
ADDED
@@ -0,0 +1,175 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class UpdraftPlus_BackupModule_ftp {
|
4 |
+
|
5 |
+
function backup($backup_array) {
|
6 |
+
|
7 |
+
global $updraftplus;
|
8 |
+
|
9 |
+
if( !class_exists('ftp_wrapper')) require_once(UPDRAFTPLUS_DIR.'/includes/ftp.class.php');
|
10 |
+
|
11 |
+
$server = UpdraftPlus_Options::get_updraft_option('updraft_server_address');
|
12 |
+
$ftp = new ftp_wrapper($server , UpdraftPlus_Options::get_updraft_option('updraft_ftp_login'), UpdraftPlus_Options::get_updraft_option('updraft_ftp_pass'));
|
13 |
+
$ftp->passive = true;
|
14 |
+
|
15 |
+
if (!$ftp->connect()) {
|
16 |
+
$ftp->ssl = true;
|
17 |
+
if (!$ftp->connect()) {
|
18 |
+
$updraftplus->log("FTP Failure: we did not successfully log in with those credentials.");
|
19 |
+
$updraftplus->error("FTP login failure");
|
20 |
+
return false;
|
21 |
+
}
|
22 |
+
}
|
23 |
+
|
24 |
+
//$ftp->make_dir(); we may need to recursively create dirs? TODO
|
25 |
+
|
26 |
+
$ftp_remote_path = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_ftp_remote_path'));
|
27 |
+
foreach($backup_array as $file) {
|
28 |
+
$fullpath = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dir')).$file;
|
29 |
+
$updraftplus->log("FTP upload attempt: $file -> ftp://$server/${ftp_remote_path}${file}");
|
30 |
+
$timer_start = microtime(true);
|
31 |
+
$size_k = round(filesize($fullpath)/1024,1);
|
32 |
+
if ($ftp->put($fullpath, $ftp_remote_path.$file, FTP_BINARY)) {
|
33 |
+
$updraftplus->log("FTP upload attempt successful (".$size_k."Kb in ".(round(microtime(true)-$timer_start,2)).'s)');
|
34 |
+
$updraftplus->uploaded_file($file);
|
35 |
+
} else {
|
36 |
+
$updraftplus->log("ERROR: FTP upload failed" );
|
37 |
+
$updraftplus->error("FTP upload failed" );
|
38 |
+
}
|
39 |
+
}
|
40 |
+
|
41 |
+
$updraftplus->prune_retained_backups("ftp", $this, array('ftp_object' => $ftp, 'ftp_remote_path' => $ftp_remote_path));
|
42 |
+
}
|
43 |
+
|
44 |
+
function delete($file, $ftparr) {
|
45 |
+
global $updraftplus;
|
46 |
+
$ftp = $ftparr['ftp_object'];
|
47 |
+
$ftp_remote_path = $ftparr['ftp_remote_path'];
|
48 |
+
if (@$ftp->delete($ftp_remote_path.$file)) {
|
49 |
+
$updraftplus->log("FTP delete: succeeded (${ftp_remote_path}${file})");
|
50 |
+
} else {
|
51 |
+
$updraftplus->log("FTP delete: failed (${ftp_remote_path}${file})");
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
+
function download($file) {
|
56 |
+
if( !class_exists('ftp_wrapper')) require_once(UPDRAFTPLUS_DIR.'/includes/ftp.class.php');
|
57 |
+
|
58 |
+
//handle errors at some point TODO
|
59 |
+
$ftp = new ftp_wrapper(UpdraftPlus_Options::get_updraft_option('updraft_server_address'),UpdraftPlus_Options::get_updraft_option('updraft_ftp_login'),UpdraftPlus_Options::get_updraft_option('updraft_ftp_pass'));
|
60 |
+
$ftp->passive = true;
|
61 |
+
|
62 |
+
if (!$ftp->connect()) {
|
63 |
+
$ftp->ssl = true;
|
64 |
+
if (!$ftp->connect()) {
|
65 |
+
$updraftplus->log("FTP Failure: we did not successfully log in with those credentials.");
|
66 |
+
$updraftplus->error("FTP login failure");
|
67 |
+
return false;
|
68 |
+
}
|
69 |
+
}
|
70 |
+
|
71 |
+
//$ftp->make_dir(); we may need to recursively create dirs? TODO
|
72 |
+
|
73 |
+
$ftp_remote_path = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_ftp_remote_path'));
|
74 |
+
$fullpath = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dir')).$file;
|
75 |
+
$ftp->get($fullpath, $ftp_remote_path.$file, FTP_BINARY);
|
76 |
+
}
|
77 |
+
|
78 |
+
public static function config_print_javascript_onready() {
|
79 |
+
?>
|
80 |
+
jQuery('#updraft-ftp-test').click(function(){
|
81 |
+
var data = {
|
82 |
+
action: 'updraft_ajax',
|
83 |
+
subaction: 'credentials_test',
|
84 |
+
method: 'ftp',
|
85 |
+
nonce: '<?php echo wp_create_nonce('updraftplus-credentialtest-nonce'); ?>',
|
86 |
+
server: jQuery('#updraft_server_address').val(),
|
87 |
+
login: jQuery('#updraft_ftp_login').val(),
|
88 |
+
pass: jQuery('#updraft_ftp_pass').val(),
|
89 |
+
path: jQuery('#updraft_ftp_remote_path').val()
|
90 |
+
};
|
91 |
+
jQuery.post(ajaxurl, data, function(response) {
|
92 |
+
alert('Settings test result: ' + response);
|
93 |
+
});
|
94 |
+
});
|
95 |
+
<?php
|
96 |
+
}
|
97 |
+
|
98 |
+
public static function config_print() {
|
99 |
+
?>
|
100 |
+
<tr class="updraftplusmethod ftp">
|
101 |
+
<th>FTP Server:</th>
|
102 |
+
<td><input type="text" size="40" id="updraft_server_address" name="updraft_server_address" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_server_address')); ?>" /> <em>Both SSL and non-SSL are supported</em></td>
|
103 |
+
</tr>
|
104 |
+
<tr class="updraftplusmethod ftp">
|
105 |
+
<th>FTP Login:</th>
|
106 |
+
<td><input type="text" size="40" id="updraft_ftp_login" name="updraft_ftp_login" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_ftp_login')) ?>" /></td>
|
107 |
+
</tr>
|
108 |
+
<tr class="updraftplusmethod ftp">
|
109 |
+
<th>FTP Password:</th>
|
110 |
+
<td><input type="text" size="40" id="updraft_ftp_pass" name="updraft_ftp_pass" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_ftp_pass')); ?>" /></td>
|
111 |
+
</tr>
|
112 |
+
<tr class="updraftplusmethod ftp">
|
113 |
+
<th>Remote Path:</th>
|
114 |
+
<td><input type="text" size="64" id="updraft_ftp_remote_path" name="updraft_ftp_remote_path" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_ftp_remote_path')); ?>" /> <em>Needs to already exist</em></td>
|
115 |
+
</tr>
|
116 |
+
<tr class="updraftplusmethod ftp">
|
117 |
+
<th></th>
|
118 |
+
<td><p><button id="updraft-ftp-test" type="button" class="button-primary" style="font-size:18px !important">Test FTP Login</button></p></td>
|
119 |
+
</tr>
|
120 |
+
<?php
|
121 |
+
}
|
122 |
+
|
123 |
+
public static function credentials_test() {
|
124 |
+
|
125 |
+
$server = $_POST['server'];
|
126 |
+
$login = $_POST['login'];
|
127 |
+
$pass = $_POST['pass'];
|
128 |
+
$path = $_POST['path'];
|
129 |
+
|
130 |
+
if (empty($server)) {
|
131 |
+
echo "Failure: No server details were given.";
|
132 |
+
return;
|
133 |
+
}
|
134 |
+
if (empty($login)) {
|
135 |
+
echo "Failure: No login was given.";
|
136 |
+
return;
|
137 |
+
}
|
138 |
+
if (empty($pass)) {
|
139 |
+
echo "Failure: No password was given.";
|
140 |
+
return;
|
141 |
+
}
|
142 |
+
|
143 |
+
if( !class_exists('ftp_wrapper')) require_once(UPDRAFTPLUS_DIR.'/includes/ftp.class.php');
|
144 |
+
|
145 |
+
//handle SSL and errors at some point TODO
|
146 |
+
$ftp = new ftp_wrapper($server, $login, $pass);
|
147 |
+
$ftp->passive = true;
|
148 |
+
|
149 |
+
if (!$ftp->connect()) {
|
150 |
+
$ftp->ssl = true;
|
151 |
+
if (!$ftp->connect()) {
|
152 |
+
echo "Failure: we did not successfully log in with those credentials.";
|
153 |
+
return;
|
154 |
+
}
|
155 |
+
}
|
156 |
+
//$ftp->make_dir(); we may need to recursively create dirs? TODO
|
157 |
+
|
158 |
+
$file = md5(rand(0,99999999)).'.tmp';
|
159 |
+
$fullpath = trailingslashit($path).$file;
|
160 |
+
if (!file_exists(ABSPATH.'wp-includes/version.php')) {
|
161 |
+
echo "Failure: an unexpected internal UpdraftPlus error occurred when testing the credentials - please contact the developer";
|
162 |
+
return;
|
163 |
+
}
|
164 |
+
if ($ftp->put(ABSPATH.'wp-includes/version.php', $fullpath, FTP_BINARY)) {
|
165 |
+
echo "Success: we successfully logged in, and confirmed our ability to create a file in the given directory.";
|
166 |
+
@$ftp->delete($fullpath);
|
167 |
+
} else {
|
168 |
+
echo "Failure: we successfully logged in, but were not able to create a file in the given directory.";
|
169 |
+
}
|
170 |
+
|
171 |
+
}
|
172 |
+
|
173 |
+
}
|
174 |
+
|
175 |
+
?>
|
trunk/methods/googledrive.php
ADDED
@@ -0,0 +1,363 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class UpdraftPlus_BackupModule_googledrive {
|
4 |
+
|
5 |
+
var $gdocs;
|
6 |
+
var $gdocs_access_token;
|
7 |
+
|
8 |
+
public static function action_auth() {
|
9 |
+
if ( isset( $_GET['state'] ) ) {
|
10 |
+
if ( $_GET['state'] == 'token' )
|
11 |
+
self::gdrive_auth_token();
|
12 |
+
elseif ( $_GET['state'] == 'revoke' )
|
13 |
+
self::gdrive_auth_revoke();
|
14 |
+
} elseif (isset($_GET['updraftplus_googleauth'])) {
|
15 |
+
self::gdrive_auth_request();
|
16 |
+
}
|
17 |
+
}
|
18 |
+
|
19 |
+
// Get a Google account access token using the refresh token
|
20 |
+
function access_token( $token, $client_id, $client_secret ) {
|
21 |
+
|
22 |
+
global $updraftplus;
|
23 |
+
$updraftplus->log("Google Drive: requesting access token: client_id=$client_id");
|
24 |
+
|
25 |
+
$query_body = array( 'refresh_token' => $token, 'client_id' => $client_id, 'client_secret' => $client_secret, 'grant_type' => 'refresh_token' );
|
26 |
+
$result = wp_remote_post('https://accounts.google.com/o/oauth2/token', array('timeout' => '15', 'method' => 'POST', 'body' => $query_body) );
|
27 |
+
|
28 |
+
if (is_wp_error($result)) {
|
29 |
+
$updraftplus->log("Google Drive error when requesting access token");
|
30 |
+
foreach ($result->get_error_messages() as $msg) { $updraftplus->log("Error message: $msg"); }
|
31 |
+
return false;
|
32 |
+
} else {
|
33 |
+
$json_values = json_decode( $result['body'], true );
|
34 |
+
if ( isset( $json_values['access_token'] ) ) {
|
35 |
+
$updraftplus->log("Google Drive: successfully obtained access token");
|
36 |
+
return $json_values['access_token'];
|
37 |
+
} else {
|
38 |
+
$updraftplus->log("Google Drive error when requesting access token: response does not contain access_token");
|
39 |
+
return false;
|
40 |
+
}
|
41 |
+
}
|
42 |
+
}
|
43 |
+
|
44 |
+
// Acquire single-use authorization code from Google OAuth 2.0
|
45 |
+
public static function gdrive_auth_request() {
|
46 |
+
// First, revoke any existing token, since Google doesn't appear to like issuing new ones
|
47 |
+
if (UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token') != "") self::gdrive_auth_revoke();
|
48 |
+
// We use 'force' here for the approval_prompt, not 'auto', as that deals better with messy situations where the user authenticated, then changed settings
|
49 |
+
$params = array(
|
50 |
+
'response_type' => 'code',
|
51 |
+
'client_id' => UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid'),
|
52 |
+
'redirect_uri' => admin_url('options-general.php?page=updraftplus&action=updraftmethod-googledrive-auth'),
|
53 |
+
'scope' => 'https://www.googleapis.com/auth/drive.file https://docs.google.com/feeds/ https://docs.googleusercontent.com/ https://spreadsheets.google.com/feeds/',
|
54 |
+
'state' => 'token',
|
55 |
+
'access_type' => 'offline',
|
56 |
+
'approval_prompt' => 'force'
|
57 |
+
);
|
58 |
+
header('Location: https://accounts.google.com/o/oauth2/auth?'.http_build_query($params));
|
59 |
+
}
|
60 |
+
|
61 |
+
// Revoke a Google account refresh token
|
62 |
+
// Returns the parameter fed in, so can be used as a WordPress options filter
|
63 |
+
public static function gdrive_auth_revoke() {
|
64 |
+
$ignore = wp_remote_get('https://accounts.google.com/o/oauth2/revoke?token='.UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token'));
|
65 |
+
UpdraftPlus_Options::update_updraft_option('updraft_googledrive_token','');
|
66 |
+
//header('Location: '.admin_url( 'options-general.php?page=updraftplus&message=Authorisation revoked'));
|
67 |
+
}
|
68 |
+
|
69 |
+
// Get a Google account refresh token using the code received from gdrive_auth_request
|
70 |
+
public static function gdrive_auth_token() {
|
71 |
+
if( isset( $_GET['code'] ) ) {
|
72 |
+
$post_vars = array(
|
73 |
+
'code' => $_GET['code'],
|
74 |
+
'client_id' => UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid'),
|
75 |
+
'client_secret' => UpdraftPlus_Options::get_updraft_option('updraft_googledrive_secret'),
|
76 |
+
'redirect_uri' => admin_url('options-general.php?page=updraftplus&action=updraftmethod-googledrive-auth'),
|
77 |
+
'grant_type' => 'authorization_code'
|
78 |
+
);
|
79 |
+
|
80 |
+
$result = wp_remote_post('https://accounts.google.com/o/oauth2/token', array('timeout' => 30, 'method' => 'POST', 'body' => $post_vars) );
|
81 |
+
|
82 |
+
if (is_wp_error($result)) {
|
83 |
+
$add_to_url = "Bad response when contacting Google: ";
|
84 |
+
foreach ( $result->get_error_messages() as $message ) {
|
85 |
+
global $updraftplus;
|
86 |
+
$updraftplus->log("Google Drive authentication error: ".$message);
|
87 |
+
$add_to_url .= "$message. ";
|
88 |
+
}
|
89 |
+
header('Location: '.admin_url('options-general.php?page=updraftplus&error='.urlencode($add_to_url)) );
|
90 |
+
} else {
|
91 |
+
$json_values = json_decode( $result['body'], true );
|
92 |
+
if ( isset( $json_values['refresh_token'] ) ) {
|
93 |
+
UpdraftPlus_Options::update_updraft_option('updraft_googledrive_token', $json_values['refresh_token']); // Save token
|
94 |
+
header('Location: '.admin_url('options-general.php?page=updraftplus&message=' . __( 'Google Drive authorisation was successful.', 'updraftplus' ) ) );
|
95 |
+
}
|
96 |
+
else {
|
97 |
+
header('Location: '.admin_url('options-general.php?page=updraftplus&error=' . __( 'No refresh token was received from Google. This often means that you entered your client secret wrongly, or that you have not yet re-authenticated (below) since correcting it. Re-check it, then follow the link to authenticate again. Finally, if that does not work, then use expert mode to wipe all your settings, create a new Google client ID/secret, and start again.', 'updraftplus' ) ) );
|
98 |
+
}
|
99 |
+
}
|
100 |
+
}
|
101 |
+
else {
|
102 |
+
header('Location: '.admin_url('options-general.php?page=updraftplus&error=' . __( 'Authorization failed!', 'updraftplus' ) ) );
|
103 |
+
}
|
104 |
+
}
|
105 |
+
|
106 |
+
// This function just does the formalities, and off-loads the main work to upload_file
|
107 |
+
function backup($backup_array) {
|
108 |
+
|
109 |
+
global $updraftplus;
|
110 |
+
|
111 |
+
if( !class_exists('UpdraftPlus_GDocs')) require_once(UPDRAFTPLUS_DIR.'/includes/class-gdocs.php');
|
112 |
+
|
113 |
+
// Do we have an access token?
|
114 |
+
if ( !$access_token = $this->access_token( UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token'), UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid'), UpdraftPlus_Options::get_updraft_option('updraft_googledrive_secret') )) {
|
115 |
+
$updraftplus->log('ERROR: Have not yet obtained an access token from Google (has the user authorised?)');
|
116 |
+
$updraftplus->error('Have not yet obtained an access token from Google - you need to authorise or re-authorise your connection to Google Drive.');
|
117 |
+
return new WP_Error( "no_access_token", "Have not yet obtained an access token from Google (has the user authorised?");
|
118 |
+
}
|
119 |
+
|
120 |
+
$this->gdocs_access_token = $access_token;
|
121 |
+
|
122 |
+
foreach ($backup_array as $file) {
|
123 |
+
$file_path = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dir')).$file;
|
124 |
+
$file_name = basename($file_path);
|
125 |
+
$updraftplus->log("$file_name: Attempting to upload to Google Drive");
|
126 |
+
$timer_start = microtime(true);
|
127 |
+
if ( $id = $this->upload_file( $file_path, $file_name, UpdraftPlus_Options::get_updraft_option('updraft_googledrive_remotepath')) ) {
|
128 |
+
$updraftplus->log('OK: Archive ' . $file_name . ' uploaded to Google Drive in ' . ( round(microtime( true ) - $timer_start,2) ) . ' seconds (id: '.$id.')' );
|
129 |
+
$updraftplus->uploaded_file($file, $id);
|
130 |
+
} else {
|
131 |
+
$updraftplus->log("ERROR: $file_name: Failed to upload to Google Drive" );
|
132 |
+
$updraftplus->error("$file_name: Failed to upload to Google Drive" );
|
133 |
+
}
|
134 |
+
}
|
135 |
+
$updraftplus->prune_retained_backups("googledrive", $this, null);
|
136 |
+
}
|
137 |
+
|
138 |
+
function delete($file) {
|
139 |
+
global $updraftplus;
|
140 |
+
$ids = UpdraftPlus_Options::get_updraft_option('updraft_file_ids', array());
|
141 |
+
if (!isset($ids[$file])) {
|
142 |
+
$updraftplus->log("Could not delete: could not find a record of the Google Drive file ID for this file");
|
143 |
+
return;
|
144 |
+
} else {
|
145 |
+
$del == $this->gdocs->delete_resource($ids[$file]);
|
146 |
+
if (is_wp_error($del)) {
|
147 |
+
foreach ($del->get_error_messages() as $msg) $updraftplus->log("Deletion failed: $msg");
|
148 |
+
} else {
|
149 |
+
$updraftplus->log("Deletion successful");
|
150 |
+
unset($ids[$file]);
|
151 |
+
UpdraftPlus_Options::update_updraft_option('updraft_file_ids', $ids);
|
152 |
+
}
|
153 |
+
}
|
154 |
+
return;
|
155 |
+
}
|
156 |
+
|
157 |
+
// Returns:
|
158 |
+
// true = already uploaded
|
159 |
+
// false = failure
|
160 |
+
// otherwise, the file ID
|
161 |
+
function upload_file( $file, $title, $parent = '') {
|
162 |
+
|
163 |
+
global $updraftplus;
|
164 |
+
|
165 |
+
// Make sure $this->gdocs is a UpdraftPlus_GDocs object, or give an error
|
166 |
+
if ( is_wp_error( $e = $this->need_gdocs() ) ) return false;
|
167 |
+
$gdocs_object = $this->gdocs;
|
168 |
+
|
169 |
+
$hash = md5($file);
|
170 |
+
$transkey = 'upd_'.$hash.'_gloc';
|
171 |
+
// This is unset upon completion, so if it is set then we are resuming
|
172 |
+
$possible_location = get_transient($transkey);
|
173 |
+
|
174 |
+
if ( empty( $possible_location ) ) {
|
175 |
+
$updraftplus->log("$file: Attempting to upload file to Google Drive.");
|
176 |
+
$location = $gdocs_object->prepare_upload( $file, $title, $parent );
|
177 |
+
} else {
|
178 |
+
$updraftplus->log("$file: Attempting to resume upload.");
|
179 |
+
$location = $gdocs_object->resume_upload( $file, $possible_location );
|
180 |
+
}
|
181 |
+
|
182 |
+
if ( is_wp_error( $location ) ) {
|
183 |
+
$updraftplus->log("GoogleDrive upload: an error occurred");
|
184 |
+
foreach ($location->get_error_messages() as $msg) {
|
185 |
+
$updraftplus->log("Error details: ".$msg);
|
186 |
+
$updraftplus->error($msg);
|
187 |
+
}
|
188 |
+
return false;
|
189 |
+
}
|
190 |
+
|
191 |
+
if (!is_string($location) && true == $location) {
|
192 |
+
$updraftplus->log("$file: this file is already uploaded");
|
193 |
+
return true;
|
194 |
+
}
|
195 |
+
|
196 |
+
if ( is_string( $location ) ) {
|
197 |
+
$res = $location;
|
198 |
+
$updraftplus->log("Uploading file with title ".$title);
|
199 |
+
$d = 0;
|
200 |
+
// This counter is only used for when deciding what to log
|
201 |
+
$counter = 0;
|
202 |
+
do {
|
203 |
+
$log_string = ($counter == 0) ? "URL: $res" : "";
|
204 |
+
$updraftplus->record_uploaded_chunk($d, $log_string);
|
205 |
+
|
206 |
+
$counter++; if ($counter >= 20) $counter=0;
|
207 |
+
|
208 |
+
$res = $gdocs_object->upload_chunk();
|
209 |
+
if (is_string($res)) set_transient($transkey, $res, UPDRAFT_TRANSTIME);
|
210 |
+
$p = $gdocs_object->get_upload_percentage();
|
211 |
+
if ( $p - $d >= 1 ) {
|
212 |
+
$b = intval( $p - $d );
|
213 |
+
// echo '<span style="width:' . $b . '%"></span>';
|
214 |
+
$d += $b;
|
215 |
+
}
|
216 |
+
// $this->options['backup_list'][$id]['speed'] = $this->gdocs->get_upload_speed();
|
217 |
+
} while ( is_string( $res ) );
|
218 |
+
// echo '</div>';
|
219 |
+
|
220 |
+
if ( is_wp_error( $res ) || $res !== true) {
|
221 |
+
$updraftplus->log( "An error occurred during GoogleDrive upload (2)" );
|
222 |
+
$updraftplus->error( "An error occurred during GoogleDrive upload (see log for more details" );
|
223 |
+
if (is_wp_error( $res )) {
|
224 |
+
foreach ($res->get_error_messages() as $msg) $updraftplus->log($msg);
|
225 |
+
}
|
226 |
+
return false;
|
227 |
+
}
|
228 |
+
|
229 |
+
$updraftplus->log("The file was successfully uploaded to Google Drive in ".number_format_i18n( $gdocs_object->time_taken(), 3)." seconds at an upload speed of ".size_format( $gdocs_object->get_upload_speed() )."/s.");
|
230 |
+
|
231 |
+
delete_transient($transkey);
|
232 |
+
// unset( $this->options['backup_list'][$id]['location'], $this->options['backup_list'][$id]['attempt'] );
|
233 |
+
}
|
234 |
+
|
235 |
+
return $gdocs_object->get_file_id();
|
236 |
+
|
237 |
+
// $this->update_quota();
|
238 |
+
// Google's "user info" service
|
239 |
+
// if ( empty( $this->options['user_info'] ) ) $this->set_user_info();
|
240 |
+
|
241 |
+
}
|
242 |
+
|
243 |
+
function download($file) {
|
244 |
+
|
245 |
+
global $updraftplus;
|
246 |
+
|
247 |
+
if( !class_exists('UpdraftPlus_GDocs')) require_once(UPDRAFTPLUS_DIR.'/includes/class-gdocs.php');
|
248 |
+
|
249 |
+
// Do we have an access token?
|
250 |
+
if ( !$access_token = $this->access_token( UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token'), UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid'), UpdraftPlus_Options::get_updraft_option('updraft_googledrive_secret') )) {
|
251 |
+
$updraftplus->error('Have not yet obtained an access token from Google (has the user authorised?)');
|
252 |
+
return false;
|
253 |
+
}
|
254 |
+
|
255 |
+
$this->gdocs_access_token = $access_token;
|
256 |
+
|
257 |
+
// Make sure $this->gdocs is a UpdraftPlus_GDocs object, or give an error
|
258 |
+
if ( is_wp_error( $e = $this->need_gdocs() ) ) return false;
|
259 |
+
$gdocs_object = $this->gdocs;
|
260 |
+
|
261 |
+
$ids = UpdraftPlus_Options::get_updraft_option('updraft_file_ids', array());
|
262 |
+
if (!isset($ids[$file])) {
|
263 |
+
$updraftplus->error("Google Drive error: $file: could not download: could not find a record of the Google Drive file ID for this file");
|
264 |
+
return;
|
265 |
+
} else {
|
266 |
+
$content_link = $gdocs_object->get_content_link( $ids[$file], $file );
|
267 |
+
if (is_wp_error($content_link)) {
|
268 |
+
$updraftplus->error("Could not find $file in order to download it (id: ".$ids[$file].")");
|
269 |
+
foreach ($content_link->get_error_messages() as $msg) $updraftplus->error($msg);
|
270 |
+
return false;
|
271 |
+
}
|
272 |
+
// Actually download the thing
|
273 |
+
$download_to = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dir')).$file;
|
274 |
+
$gdocs_object->download_data($content_link, $download_to);
|
275 |
+
|
276 |
+
if (filesize($download_to) >0) {
|
277 |
+
return true;
|
278 |
+
} else {
|
279 |
+
$updraftplus->error("Google Drive error: zero-size file was downloaded");
|
280 |
+
return false;
|
281 |
+
}
|
282 |
+
|
283 |
+
}
|
284 |
+
|
285 |
+
return;
|
286 |
+
|
287 |
+
}
|
288 |
+
|
289 |
+
// This function modified from wordpress.org/extend/plugins/backup, by Sorin Iclanzan, under the GPLv3 or later at your choice
|
290 |
+
function need_gdocs() {
|
291 |
+
|
292 |
+
global $updraftplus;
|
293 |
+
|
294 |
+
if ( ! $this->is_gdocs($this->gdocs) ) {
|
295 |
+
if ( UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token') == "" || UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid') == "" || UpdraftPlus_Options::get_updraft_option('updraft_googledrive_secret') == "" ) {
|
296 |
+
$updraftplus->log("GoogleDrive: this account is not authorised");
|
297 |
+
return new WP_Error( "not_authorized", "Account is not authorized." );
|
298 |
+
}
|
299 |
+
|
300 |
+
if ( is_wp_error( $this->gdocs_access_token ) ) return $access_token;
|
301 |
+
|
302 |
+
$this->gdocs = new UpdraftPlus_GDocs( $this->gdocs_access_token );
|
303 |
+
// We need to be able to upload at least one chunk within the timeout (at least, we have seen an error report where the failure to do this seemed to be the cause)
|
304 |
+
// If we assume a user has at least 16kb/s (we saw one user with as low as 22kb/s), and that their provider may allow them only 15s, then we have the following settings
|
305 |
+
$this->gdocs->set_option( 'chunk_size', 0.2 ); # 0.2Mb; change from default of 512Kb
|
306 |
+
$this->gdocs->set_option( 'request_timeout', 15 ); # Change from default of 5s
|
307 |
+
$this->gdocs->set_option( 'max_resume_attempts', 36 ); # Doesn't look like GDocs class actually uses this anyway
|
308 |
+
}
|
309 |
+
return true;
|
310 |
+
}
|
311 |
+
|
312 |
+
// This function taken from wordpress.org/extend/plugins/backup, by Sorin Iclanzan, under the GPLv3 or later at your choice
|
313 |
+
function is_gdocs( $thing ) {
|
314 |
+
if ( is_object( $thing ) && is_a( $thing, 'UpdraftPlus_GDocs' ) ) return true;
|
315 |
+
return false;
|
316 |
+
}
|
317 |
+
|
318 |
+
public static function config_print() {
|
319 |
+
?>
|
320 |
+
<tr class="updraftplusmethod googledrive">
|
321 |
+
<td>Google Drive:</td>
|
322 |
+
<td>
|
323 |
+
<img src="https://developers.google.com/drive/images/drive_logo.png" alt="Google Drive">
|
324 |
+
<p><em>Google Drive is a great choice, because UpdraftPlus supports chunked uploads - no matter how big your blog is, UpdraftPlus can upload it a little at a time, and not get thwarted by timeouts.</em></p>
|
325 |
+
</td>
|
326 |
+
</tr>
|
327 |
+
<tr class="updraftplusmethod googledrive">
|
328 |
+
<th>Google Drive:</th>
|
329 |
+
<td>
|
330 |
+
<p><a href="http://updraftplus.com/support/configuring-google-drive-api-access-in-updraftplus/"><strong>For longer help, including screenshots, follow this link. The description below is sufficient for more expert users.</strong></a></p>
|
331 |
+
<p><a href="https://code.google.com/apis/console/">Follow this link to your Google API Console</a>, and there create a Client ID in the API Access section. Select 'Web Application' as the application type.</p><p>You must add <kbd><?php echo admin_url('options-general.php?page=updraftplus&action=updraftmethod-googledrive-auth'); ?></kbd> as the authorised redirect URI (under "More Options") when asked. N.B. If you install UpdraftPlus on several WordPress sites, then you cannot re-use your client ID; you must create a new one from your Google API console for each blog.
|
332 |
+
|
333 |
+
<?php
|
334 |
+
if (!class_exists('SimpleXMLElement')) { echo " <b>WARNING:</b> You do not have the SimpleXMLElement installed. Google Drive backups will <b>not</b> work until you do."; }
|
335 |
+
?>
|
336 |
+
</p>
|
337 |
+
</td>
|
338 |
+
</tr>
|
339 |
+
|
340 |
+
<tr class="updraftplusmethod googledrive">
|
341 |
+
<th>Google Drive Client ID:</th>
|
342 |
+
<td><input type="text" autocomplete="off" style="width:352px" name="updraft_googledrive_clientid" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid')) ?>" /><br><em>If Google later shows you the message "invalid_client", then you did not enter a valid client ID here.</em></td>
|
343 |
+
</tr>
|
344 |
+
<tr class="updraftplusmethod googledrive">
|
345 |
+
<th>Google Drive Client Secret:</th>
|
346 |
+
<td><input type="text" style="width:352px" name="updraft_googledrive_secret" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_googledrive_secret')); ?>" /></td>
|
347 |
+
</tr>
|
348 |
+
<tr class="updraftplusmethod googledrive">
|
349 |
+
<th>Google Drive Folder ID:</th>
|
350 |
+
<td><input type="text" style="width:352px" name="updraft_googledrive_remotepath" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_googledrive_remotepath')); ?>" /> <em><strong>This is NOT a folder name</strong>. To get a folder's ID navigate to that folder in Google Drive in your web browser and copy the ID from your browser's address bar. It is the part that comes after <kbd>#folders/.</kbd> Leave empty to use your root folder)</em></td>
|
351 |
+
</tr>
|
352 |
+
<tr class="updraftplusmethod googledrive">
|
353 |
+
<th>Authenticate with Google:</th>
|
354 |
+
<td><p><?php if (UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token') != "") echo "<strong>(You appear to be already authenticated,</strong> though you can authenticate again to refresh your access if you've had a problem).</strong>"; ?> <a href="options-general.php?page=updraftplus&action=updraftmethod-googledrive-auth&updraftplus_googleauth=doit"><strong>After</strong> you have saved your settings (by clicking "Save Changes" below), then come back here once and click this link to complete authentication with Google.</a>
|
355 |
+
</p>
|
356 |
+
</td>
|
357 |
+
</tr>
|
358 |
+
<?php
|
359 |
+
}
|
360 |
+
|
361 |
+
}
|
362 |
+
|
363 |
+
?>
|
trunk/methods/s3.php
ADDED
@@ -0,0 +1,328 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class UpdraftPlus_BackupModule_s3 {
|
4 |
+
|
5 |
+
function getS3($key, $secret) {
|
6 |
+
return new S3($key, $secret);
|
7 |
+
}
|
8 |
+
|
9 |
+
function set_endpoint($obj, $region) {
|
10 |
+
switch ($region) {
|
11 |
+
case 'EU':
|
12 |
+
case 'eu-west-1':
|
13 |
+
$endpoint = 's3-eu-west-1.amazonaws.com';
|
14 |
+
break;
|
15 |
+
case 'us-west-1':
|
16 |
+
case 'us-west-2':
|
17 |
+
case 'ap-southeast-1':
|
18 |
+
case 'ap-southeast-2':
|
19 |
+
case 'ap-northeast-1':
|
20 |
+
case 'sa-east-1':
|
21 |
+
$endpoint = 's3-'.$region.'.amazonaws.com';
|
22 |
+
break;
|
23 |
+
default:
|
24 |
+
break;
|
25 |
+
}
|
26 |
+
if (isset($endpoint)) {
|
27 |
+
$obj->setEndpoint($endpoint);
|
28 |
+
}
|
29 |
+
}
|
30 |
+
|
31 |
+
function backup($backup_array) {
|
32 |
+
|
33 |
+
global $updraftplus;
|
34 |
+
|
35 |
+
if (!class_exists('S3')) require_once(UPDRAFTPLUS_DIR.'/includes/S3.php');
|
36 |
+
|
37 |
+
$s3 = $this->getS3(UpdraftPlus_Options::get_updraft_option('updraft_s3_login'), UpdraftPlus_Options::get_updraft_option('updraft_s3_pass'));
|
38 |
+
|
39 |
+
$bucket_name = untrailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_s3_remote_path'));
|
40 |
+
$bucket_path = "";
|
41 |
+
$orig_bucket_name = $bucket_name;
|
42 |
+
|
43 |
+
if (preg_match("#^([^/]+)/(.*)$#",$bucket_name,$bmatches)) {
|
44 |
+
$bucket_name = $bmatches[1];
|
45 |
+
$bucket_path = $bmatches[2]."/";
|
46 |
+
}
|
47 |
+
|
48 |
+
$region = @$s3->getBucketLocation($bucket_name);
|
49 |
+
|
50 |
+
// See if we can detect the region (which implies the bucket exists and is ours), or if not create it
|
51 |
+
if (!empty($region) || @$s3->putBucket($bucket_name, S3::ACL_PRIVATE)) {
|
52 |
+
|
53 |
+
if (empty($region)) $region = $s3->getBucketLocation($bucket_name);
|
54 |
+
$this->set_endpoint($s3, $region);
|
55 |
+
|
56 |
+
foreach($backup_array as $key => $file) {
|
57 |
+
|
58 |
+
// We upload in 5Mb chunks to allow more efficient resuming and hence uploading of larger files
|
59 |
+
// N.B.: 5Mb is Amazon's minimum. So don't go lower or you'll break it.
|
60 |
+
$fullpath = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dir')).$file;
|
61 |
+
$orig_file_size = filesize($fullpath);
|
62 |
+
$chunks = floor($orig_file_size / 5242880);
|
63 |
+
// There will be a remnant unless the file size was exactly on a 5Mb boundary
|
64 |
+
if ($orig_file_size % 5242880 > 0 ) $chunks++;
|
65 |
+
$hash = md5($file);
|
66 |
+
|
67 |
+
$updraftplus->log("S3 upload ($region): $fullpath (chunks: $chunks) -> s3://$bucket_name/$bucket_path$file");
|
68 |
+
|
69 |
+
$filepath = $bucket_path.$file;
|
70 |
+
|
71 |
+
// This is extra code for the 1-chunk case, but less overhead (no bothering with transients)
|
72 |
+
if ($chunks < 2) {
|
73 |
+
if (!$s3->putObjectFile($fullpath, $bucket_name, $filepath)) {
|
74 |
+
$updraftplus->log("S3 regular upload: failed ($fullpath)");
|
75 |
+
$updraftplus->error("S3 Error: Failed to upload $file.");
|
76 |
+
} else {
|
77 |
+
$updraftplus->log("S3 regular upload: success");
|
78 |
+
$updraftplus->uploaded_file($file);
|
79 |
+
}
|
80 |
+
} else {
|
81 |
+
|
82 |
+
// Retrieve the upload ID
|
83 |
+
$uploadId = get_transient("updraft_${hash}_uid");
|
84 |
+
if (empty($uploadId)) {
|
85 |
+
$s3->setExceptions(true);
|
86 |
+
try {
|
87 |
+
$uploadId = $s3->initiateMultipartUpload($bucket_name, $filepath);
|
88 |
+
} catch (Exception $e) {
|
89 |
+
$updraftplus->log('S3 error whilst trying initiateMultipartUpload: '.$e->getMessage().' (line: '.$e->getLine().', file: '.$e->getFile().')');
|
90 |
+
$s3->setExceptions(false);
|
91 |
+
$uploadId = false;
|
92 |
+
}
|
93 |
+
$s3->setExceptions(false);
|
94 |
+
|
95 |
+
if (empty($uploadId)) {
|
96 |
+
$updraftplus->log("S3 upload: failed: could not get uploadId for multipart upload ($filepath)");
|
97 |
+
$updraftplus->error("S3 upload: getting uploadID for multipart upload failed - see log file for more details");
|
98 |
+
continue;
|
99 |
+
} else {
|
100 |
+
$updraftplus->log("S3 chunked upload: got multipart ID: $uploadId");
|
101 |
+
set_transient("updraft_${hash}_uid", $uploadId, UPDRAFT_TRANSTIME);
|
102 |
+
}
|
103 |
+
} else {
|
104 |
+
$updraftplus->log("S3 chunked upload: retrieved previously obtained multipart ID: $uploadId");
|
105 |
+
}
|
106 |
+
|
107 |
+
$successes = 0;
|
108 |
+
$etags = array();
|
109 |
+
for ($i = 1 ; $i <= $chunks; $i++) {
|
110 |
+
# Shorted to upd here to avoid hitting the 45-character limit
|
111 |
+
$etag = get_transient("upd_${hash}_e$i");
|
112 |
+
if (strlen($etag) > 0) {
|
113 |
+
$updraftplus->log("S3 chunk $i: was already completed (etag: $etag)");
|
114 |
+
$successes++;
|
115 |
+
array_push($etags, $etag);
|
116 |
+
} else {
|
117 |
+
// Sanity check: we've seen a case where an overlap was truncating the file from underneath us
|
118 |
+
if (filesize($fullpath) < $orig_file_size) {
|
119 |
+
$updraftplus->error("S3 error: $key: chunk $i: file was truncated underneath us (orig_size=$orig_file_size, now_size=".filesize($fullpath).")");
|
120 |
+
}
|
121 |
+
$etag = $s3->uploadPart($bucket_name, $filepath, $uploadId, $fullpath, $i);
|
122 |
+
if ($etag !== false && is_string($etag)) {
|
123 |
+
$updraftplus->record_uploaded_chunk(round(100*$i/$chunks,1), "$i, $etag");
|
124 |
+
array_push($etags, $etag);
|
125 |
+
set_transient("upd_${hash}_e$i", $etag, UPDRAFT_TRANSTIME);
|
126 |
+
$successes++;
|
127 |
+
} else {
|
128 |
+
$updraftplus->log("S3 chunk $i: upload failed");
|
129 |
+
$updraftplus->error("S3 chunk $i: upload failed");
|
130 |
+
}
|
131 |
+
}
|
132 |
+
}
|
133 |
+
if ($successes >= $chunks) {
|
134 |
+
$updraftplus->log("S3 upload: all chunks uploaded; will now instruct S3 to re-assemble");
|
135 |
+
|
136 |
+
$s3->setExceptions(true);
|
137 |
+
try {
|
138 |
+
if ($s3->completeMultipartUpload ($bucket_name, $filepath, $uploadId, $etags)) {
|
139 |
+
$updraftplus->log("S3 upload ($key): re-assembly succeeded");
|
140 |
+
$updraftplus->uploaded_file($file);
|
141 |
+
} else {
|
142 |
+
$updraftplus->log("S3 upload ($key): re-assembly failed");
|
143 |
+
$updraftplus->error("S3 upload ($key): re-assembly failed ($file)");
|
144 |
+
}
|
145 |
+
} catch (Exception $e) {
|
146 |
+
$updraftplus->log("S3 re-assembly error ($key): ".$e->getMessage().' (line: '.$e->getLine().', file: '.$e->getFile().')');
|
147 |
+
$updraftplus->error("S3 re-assembly error ($key): ".$e->getMessage().' (see log file for more)');
|
148 |
+
}
|
149 |
+
// Remember to unset, as the deletion code later reuses the object
|
150 |
+
$s3->setExceptions(false);
|
151 |
+
} else {
|
152 |
+
$updraftplus->log("S3 upload: upload was not completely successful on this run");
|
153 |
+
}
|
154 |
+
}
|
155 |
+
}
|
156 |
+
$updraftplus->prune_retained_backups('s3', $this, array('s3_object' => $s3, 's3_orig_bucket_name' => $orig_bucket_name));
|
157 |
+
} else {
|
158 |
+
$updraftplus->log("S3 Error: Failed to create bucket $bucket_name.");
|
159 |
+
$updraftplus->error("S3 Error: Failed to create bucket $bucket_name. Check your permissions and credentials.");
|
160 |
+
}
|
161 |
+
}
|
162 |
+
|
163 |
+
function delete($file, $s3arr) {
|
164 |
+
|
165 |
+
global $updraftplus;
|
166 |
+
|
167 |
+
$s3 = $s3arr['s3_object'];
|
168 |
+
$orig_bucket_name = $s3arr['s3_orig_bucket_name'];
|
169 |
+
|
170 |
+
if (preg_match("#^([^/]+)/(.*)$#", $orig_bucket_name, $bmatches)) {
|
171 |
+
$s3_bucket=$bmatches[1];
|
172 |
+
$s3_uri = $bmatches[2]."/".$file;
|
173 |
+
} else {
|
174 |
+
$s3_bucket = $orig_bucket_name;
|
175 |
+
$s3_uri = $file;
|
176 |
+
}
|
177 |
+
$updraftplus->log("S3: Delete remote: bucket=$s3_bucket, URI=$s3_uri");
|
178 |
+
|
179 |
+
$s3->setExceptions(true);
|
180 |
+
try {
|
181 |
+
if (!$s3->deleteObject($s3_bucket, $s3_uri)) {
|
182 |
+
$updraftplus->log("S3: Delete failed");
|
183 |
+
}
|
184 |
+
} catch (Exception $e) {
|
185 |
+
$updraftplus->log('S3 delete failed: '.$e->getMessage().' (line: '.$e->getLine().', file: '.$e->getFile().')');
|
186 |
+
}
|
187 |
+
$s3->setExceptions(false);
|
188 |
+
|
189 |
+
}
|
190 |
+
|
191 |
+
function download($file) {
|
192 |
+
|
193 |
+
global $updraftplus;
|
194 |
+
if(!class_exists('S3')) require_once(UPDRAFTPLUS_DIR.'/includes/S3.php');
|
195 |
+
|
196 |
+
$s3 = $this->getS3(UpdraftPlus_Options::get_updraft_option('updraft_s3_login'), UpdraftPlus_Options::get_updraft_option('updraft_s3_pass'));
|
197 |
+
|
198 |
+
$bucket_name = untrailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_s3_remote_path'));
|
199 |
+
$bucket_path = "";
|
200 |
+
|
201 |
+
if (preg_match("#^([^/]+)/(.*)$#", $bucket_name, $bmatches)) {
|
202 |
+
$bucket_name = $bmatches[1];
|
203 |
+
$bucket_path = $bmatches[2]."/";
|
204 |
+
}
|
205 |
+
|
206 |
+
$region = @$s3->getBucketLocation($bucket_name);
|
207 |
+
if (!empty($region)) {
|
208 |
+
$this->set_endpoint($s3, $region);
|
209 |
+
$fullpath = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dir')).$file;
|
210 |
+
if (!$s3->getObject($bucket_name, $bucket_path.$file, $fullpath)) {
|
211 |
+
$updraftplus->error("S3 Error: Failed to download $file. Check your permissions and credentials.");
|
212 |
+
}
|
213 |
+
} else {
|
214 |
+
$updraftplus->error("S3 Error: Failed to access bucket $bucket_name. Check your permissions and credentials.");
|
215 |
+
}
|
216 |
+
|
217 |
+
}
|
218 |
+
|
219 |
+
public static function config_print_javascript_onready() {
|
220 |
+
?>
|
221 |
+
jQuery('#updraft-s3-test').click(function(){
|
222 |
+
var data = {
|
223 |
+
action: 'updraft_ajax',
|
224 |
+
subaction: 'credentials_test',
|
225 |
+
method: 's3',
|
226 |
+
nonce: '<?php echo wp_create_nonce('updraftplus-credentialtest-nonce'); ?>',
|
227 |
+
apikey: jQuery('#updraft_s3_apikey').val(),
|
228 |
+
apisecret: jQuery('#updraft_s3_apisecret').val(),
|
229 |
+
path: jQuery('#updraft_s3_path').val()
|
230 |
+
};
|
231 |
+
jQuery.post(ajaxurl, data, function(response) {
|
232 |
+
alert('Settings test result: ' + response);
|
233 |
+
});
|
234 |
+
});
|
235 |
+
<?php
|
236 |
+
}
|
237 |
+
|
238 |
+
public static function config_print() {
|
239 |
+
|
240 |
+
?>
|
241 |
+
<tr class="updraftplusmethod s3">
|
242 |
+
<td></td>
|
243 |
+
<td><img src="https://d36cz9buwru1tt.cloudfront.net/Powered-by-Amazon-Web-Services.jpg" alt="Amazon Web Services"><p><em>Amazon S3 is a great choice, because UpdraftPlus supports chunked uploads - no matter how big your blog is, UpdraftPlus can upload it a little at a time, and not get thwarted by timeouts.</em></p></td>
|
244 |
+
</tr>
|
245 |
+
<tr class="updraftplusmethod s3">
|
246 |
+
<th></th>
|
247 |
+
<td>
|
248 |
+
<p>Get your access key and secret key <a href="http://aws.amazon.com/console/">from your AWS console</a>, then pick a (globally unique - all Amazon S3 users) bucket name (letters and numbers) (and optionally a path) to use for storage. This bucket will be created for you if it does not already exist.</p>
|
249 |
+
</td></tr>
|
250 |
+
<tr class="updraftplusmethod s3">
|
251 |
+
<th>S3 access key:</th>
|
252 |
+
<td><input type="text" autocomplete="off" style="width: 292px" id="updraft_s3_apikey" name="updraft_s3_login" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_s3_login')) ?>" /></td>
|
253 |
+
</tr>
|
254 |
+
<tr class="updraftplusmethod s3">
|
255 |
+
<th>S3 secret key:</th>
|
256 |
+
<td><input type="text" autocomplete="off" style="width: 292px" id="updraft_s3_apisecret" name="updraft_s3_pass" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_s3_pass')); ?>" /></td>
|
257 |
+
</tr>
|
258 |
+
<tr class="updraftplusmethod s3">
|
259 |
+
<th>S3 location:</th>
|
260 |
+
<td>s3://<input type="text" style="width: 292px" name="updraft_s3_remote_path" id="updraft_s3_path" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_s3_remote_path')); ?>" /></td>
|
261 |
+
</tr>
|
262 |
+
<tr class="updraftplusmethod s3">
|
263 |
+
<th></th>
|
264 |
+
<td><p><button id="updraft-s3-test" type="button" class="button-primary" style="font-size:18px !important">Test S3 Settings</button></p></td>
|
265 |
+
</tr>
|
266 |
+
<?php
|
267 |
+
}
|
268 |
+
|
269 |
+
public static function credentials_test() {
|
270 |
+
|
271 |
+
$key = $_POST['apikey'];
|
272 |
+
$secret = $_POST['apisecret'];
|
273 |
+
$path = $_POST['path'];
|
274 |
+
|
275 |
+
if (preg_match("#^([^/]+)/(.*)$#", $path, $bmatches)) {
|
276 |
+
$bucket = $bmatches[1];
|
277 |
+
$path = $bmatches[2];
|
278 |
+
} else {
|
279 |
+
$bucket = $path;
|
280 |
+
$path = "";
|
281 |
+
}
|
282 |
+
|
283 |
+
if (empty($bucket)) {
|
284 |
+
echo "Failure: No bucket details were given.";
|
285 |
+
return;
|
286 |
+
}
|
287 |
+
if (empty($key)) {
|
288 |
+
echo "Failure: No API key was given.";
|
289 |
+
return;
|
290 |
+
}
|
291 |
+
if (empty($secret)) {
|
292 |
+
echo "Failure: No API secret was given.";
|
293 |
+
return;
|
294 |
+
}
|
295 |
+
|
296 |
+
if (!class_exists('S3')) require_once(UPDRAFTPLUS_DIR.'/includes/S3.php');
|
297 |
+
$s3 = new S3($key, $secret);
|
298 |
+
|
299 |
+
$location = @$s3->getBucketLocation($bucket);
|
300 |
+
if ($location) {
|
301 |
+
$bucket_exists = true;
|
302 |
+
$bucket_verb = "accessed (Amazon region: $location)";
|
303 |
+
$bucket_region = $location;
|
304 |
+
} else {
|
305 |
+
$try_to_create_bucket = @$s3->putBucket($bucket, S3::ACL_PRIVATE);
|
306 |
+
if ($try_to_create_bucket) {
|
307 |
+
$bucket_verb = 'created';
|
308 |
+
$bucket_exists = true;
|
309 |
+
} else {
|
310 |
+
echo "Failure: We could not successfully access or create such a bucket. Please check your access credentials, and if those are correct then try another bucket name (as another S3 user may already have taken your name).";
|
311 |
+
}
|
312 |
+
}
|
313 |
+
|
314 |
+
if (isset($bucket_exists)) {
|
315 |
+
$try_file = md5(rand());
|
316 |
+
$this->set_endpoint($s3, $location);
|
317 |
+
if (!$s3->putObjectString($try_file, $bucket, $path.$try_file)) {
|
318 |
+
echo "Failure: We successfully $bucket_verb the bucket, but the attempt to create a file in it failed.";
|
319 |
+
} else {
|
320 |
+
echo "Success: we $bucket_verb the bucket, and were able to create files within it.";
|
321 |
+
@$s3->deleteObject($bucket, $path.$try_file);
|
322 |
+
}
|
323 |
+
}
|
324 |
+
|
325 |
+
}
|
326 |
+
|
327 |
+
}
|
328 |
+
?>
|
trunk/methods/template.php
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
|
5 |
+
This is a bare-bones to get you started with developing an access method. The methods provided below are all ones you will want to use (though note that the provided email.php method is an example of truly bare-bones for a method that cannot delete or download and has no configuration).
|
6 |
+
|
7 |
+
Read the existing methods for help. There is no hard-and-fast need to put all your code in this file; it is just for increasing convenience and maintainability; there are no bonus points for 100% elegance. If you need access to some part of WordPress that you can only reach through the main plugin file (updraftplus.php), then go right ahead and patch that.
|
8 |
+
|
9 |
+
Some handy tips:
|
10 |
+
- Search-and-replace "template" for the name of your access method
|
11 |
+
- You can also add the methods config_print_javascript_onready and credentials_test if you like; see s3.php as an example of how these are used (to provide a "Test Settings" button via AJAX in the settings page)
|
12 |
+
- Name your file accordingly (it is now template.php)
|
13 |
+
- Add the method to the array $backup_methods in updraftplus.php when ready
|
14 |
+
- Use the constant UPDRAFTPLUS_DIR to reach Updraft's plugin directory
|
15 |
+
- Call $updraftplus->log("my log message") to log things, which greatly helps debugging
|
16 |
+
- UpdraftPlus is licenced under the GPLv3 or later. In order to combine your backup method with UpdraftPlus, you will need to licence to anyone and everyone that you distribute it to in a compatible way.
|
17 |
+
|
18 |
+
*/
|
19 |
+
|
20 |
+
class UpdraftPlus_BackupModule_template {
|
21 |
+
|
22 |
+
// backup method: takes an array, and shovels them off to the cloud storage
|
23 |
+
function backup($backup_array) {
|
24 |
+
|
25 |
+
global $updraftplus;
|
26 |
+
|
27 |
+
foreach ($backup_array as $file) {
|
28 |
+
|
29 |
+
// Do our uploading stuff...
|
30 |
+
|
31 |
+
// If successful, then you must do this:
|
32 |
+
// $updraftplus->uploaded_file($file);
|
33 |
+
|
34 |
+
}
|
35 |
+
|
36 |
+
}
|
37 |
+
|
38 |
+
// delete method: takes a file name (base name), and removes it from the cloud storage
|
39 |
+
function delete($file) {
|
40 |
+
|
41 |
+
global $updraftplus;
|
42 |
+
|
43 |
+
}
|
44 |
+
|
45 |
+
// download method: takes a file name (base name), and brings it back from the cloud storage into Updraft's directory
|
46 |
+
// $updraftplus->logging is not available here, but you can register errors with $updraftplus->error("my error message")
|
47 |
+
function download($file) {
|
48 |
+
|
49 |
+
global $updraftplus;
|
50 |
+
|
51 |
+
}
|
52 |
+
|
53 |
+
// config_print: prints out table rows for the configuration screen
|
54 |
+
// Your rows need to have a class exactly matching your method (in this example, template), and also a class of updraftplusmethod
|
55 |
+
// Note that logging is not available from this context; it will do nothing.
|
56 |
+
function config_print() {
|
57 |
+
|
58 |
+
?>
|
59 |
+
<tr class="updraftplusmethod template">
|
60 |
+
<th>My Method:</th>
|
61 |
+
<td>
|
62 |
+
|
63 |
+
</td>
|
64 |
+
</tr>
|
65 |
+
|
66 |
+
<?php
|
67 |
+
|
68 |
+
|
69 |
+
}
|
70 |
+
|
71 |
+
}
|
trunk/options.php
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Options handling
|
4 |
+
if (!defined ('ABSPATH')) die ('No direct access allowed');
|
5 |
+
|
6 |
+
class UpdraftPlus_Options {
|
7 |
+
|
8 |
+
public static function user_can_manage() {
|
9 |
+
return current_user_can('manage_options');
|
10 |
+
}
|
11 |
+
|
12 |
+
public static function get_updraft_option($option, $default = null) {
|
13 |
+
return get_option($option, $default);
|
14 |
+
}
|
15 |
+
|
16 |
+
public static function update_updraft_option($option, $value) {
|
17 |
+
update_option($option, $value);
|
18 |
+
}
|
19 |
+
|
20 |
+
public static function delete_updraft_option($option) {
|
21 |
+
delete_option($option, $value);
|
22 |
+
}
|
23 |
+
|
24 |
+
public static function add_admin_pages() {
|
25 |
+
global $updraftplus;
|
26 |
+
add_submenu_page('options-general.php', "UpdraftPlus", "UpdraftPlus", "manage_options", "updraftplus", array($updraftplus, "settings_output"));
|
27 |
+
}
|
28 |
+
|
29 |
+
public static function options_form_begin() {
|
30 |
+
echo '<form method="post" action="options.php">';
|
31 |
+
settings_fields('updraft-options-group');
|
32 |
+
}
|
33 |
+
|
34 |
+
public static function admin_init() {
|
35 |
+
|
36 |
+
global $updraftplus;
|
37 |
+
register_setting('updraft-options-group', 'updraft_interval', array($updraftplus, 'schedule_backup') );
|
38 |
+
register_setting('updraft-options-group', 'updraft_interval_database', array($updraftplus, 'schedule_backup_database') );
|
39 |
+
register_setting('updraft-options-group', 'updraft_retain', array($updraftplus, 'retain_range') );
|
40 |
+
register_setting('updraft-options-group', 'updraft_retain_db', array($updraftplus, 'retain_range') );
|
41 |
+
register_setting('updraft-options-group', 'updraft_encryptionphrase');
|
42 |
+
register_setting('updraft-options-group', 'updraft_service' );
|
43 |
+
|
44 |
+
register_setting('updraft-options-group', 'updraft_s3_login' );
|
45 |
+
register_setting('updraft-options-group', 'updraft_s3_pass' );
|
46 |
+
register_setting('updraft-options-group', 'updraft_s3_remote_path' );
|
47 |
+
|
48 |
+
register_setting('updraft-options-group', 'updraft_dropbox_appkey' );
|
49 |
+
register_setting('updraft-options-group', 'updraft_dropbox_secret' );
|
50 |
+
register_setting('updraft-options-group', 'updraft_dropbox_folder' );
|
51 |
+
|
52 |
+
register_setting('updraft-options-group', 'updraft_googledrive_clientid', array($updraftplus, 'googledrive_clientid_checkchange') );
|
53 |
+
register_setting('updraft-options-group', 'updraft_googledrive_secret' );
|
54 |
+
register_setting('updraft-options-group', 'updraft_googledrive_remotepath' );
|
55 |
+
register_setting('updraft-options-group', 'updraft_ftp_login' );
|
56 |
+
register_setting('updraft-options-group', 'updraft_ftp_pass' );
|
57 |
+
register_setting('updraft-options-group', 'updraft_ftp_remote_path' );
|
58 |
+
register_setting('updraft-options-group', 'updraft_server_address' );
|
59 |
+
register_setting('updraft-options-group', 'updraft_dir' );
|
60 |
+
register_setting('updraft-options-group', 'updraft_email');
|
61 |
+
register_setting('updraft-options-group', 'updraft_delete_local', 'absint' );
|
62 |
+
register_setting('updraft-options-group', 'updraft_debug_mode', 'absint' );
|
63 |
+
register_setting('updraft-options-group', 'updraft_include_plugins', 'absint' );
|
64 |
+
register_setting('updraft-options-group', 'updraft_include_themes', 'absint' );
|
65 |
+
register_setting('updraft-options-group', 'updraft_include_uploads', 'absint' );
|
66 |
+
register_setting('updraft-options-group', 'updraft_include_others', 'absint' );
|
67 |
+
register_setting('updraft-options-group', 'updraft_include_others_exclude' );
|
68 |
+
|
69 |
+
register_setting('updraft-options-group', 'updraft_starttime_files', array($updraftplus, 'hourminute') );
|
70 |
+
register_setting('updraft-options-group', 'updraft_starttime_db', array($updraftplus, 'hourminute') );
|
71 |
+
|
72 |
+
global $pagenow;
|
73 |
+
if (is_multisite() && $pagenow == 'options-general.php') {
|
74 |
+
add_action('admin_notices', array('UpdraftPlus_Options', 'show_admin_warning_multisite') );
|
75 |
+
}
|
76 |
+
|
77 |
+
}
|
78 |
+
|
79 |
+
public static function show_admin_warning_multisite() {
|
80 |
+
|
81 |
+
global $updraftplus;
|
82 |
+
|
83 |
+
$updraftplus->show_admin_warning('<strong>UpdraftPlus warning:</strong> This is a WordPress multi-site (a.k.a. network) installation. <a href="http://updraftplus.com">WordPress Multisite is supported by UpdraftPlus Premium</a>. Non-premium UpdraftPlus does not support multi-site installations securely. <strong>Every</strong> blog admin can both back up (and hence access the data, including passwords, from) and restore (including with customised modifications, e.g. changed passwords) <strong>the entire network</strong>. Unless you are the only blog admin user across the entire network, you should immediately de-activate UpdraftPlus. (This applies to all WordPress backup plugins unless they have been explicitly coded for multisite compatibility).', "error");
|
84 |
+
|
85 |
+
}
|
86 |
+
|
87 |
+
|
88 |
+
}
|
89 |
+
|
90 |
+
add_action('admin_init', array('UpdraftPlus_Options', 'admin_init'));
|
91 |
+
add_action('admin_menu', array('UpdraftPlus_Options', 'add_admin_pages'));
|
92 |
+
|
93 |
+
?>
|
trunk/readme.txt
ADDED
@@ -0,0 +1,335 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
=== UpdraftPlus Backup ===
|
2 |
+
Contributors: David Anderson
|
3 |
+
Tags: backup, restore, database, cloud, amazon, s3, dropbox, google drive, ftp, cloud, back up, multisite
|
4 |
+
Requires at least: 3.2
|
5 |
+
Tested up to: 3.5.1
|
6 |
+
Stable tag: 1.4.13
|
7 |
+
Author URI: http://updraftplus.com
|
8 |
+
Donate link: http://david.dw-perspective.org.uk/donate
|
9 |
+
License: GPLv3 or later
|
10 |
+
|
11 |
+
== Upgrade Notice ==
|
12 |
+
Minor tweaks
|
13 |
+
|
14 |
+
== Description ==
|
15 |
+
|
16 |
+
<a href="http://updraftplus.com">UpdraftPlus</a> simplifies backups (and restoration). Backup into the cloud (Amazon S3, Dropbox, Google Drive, FTP, and email) and restore with a single click. Backups of files and database can have separate schedules.
|
17 |
+
|
18 |
+
* Supports backups to Amazon S3, Dropbox, Google Drive, FTP (including SSL), email
|
19 |
+
* One-click restore
|
20 |
+
* Backup automatically on a repeating schedule
|
21 |
+
* Files and databases can have separate schedules
|
22 |
+
* Failed uploads are automatically resumed/retried
|
23 |
+
* Select which files to backup (plugins, themes, content, other)
|
24 |
+
* Database backups can be encrypted for security
|
25 |
+
* Debug mode that gives full logging of the backup
|
26 |
+
* Thousands of users: widely tested and reliable
|
27 |
+
* Premium/multi-site version and support available - <a href="http://updraftplus.com">http://updraftplus.com</a>
|
28 |
+
|
29 |
+
= Best New WordPress Plugin =
|
30 |
+
|
31 |
+
That's according to WordPress big cheese, Vladimir Prelovac. Check out his weekly chart to see where UpdraftPlus is right now: http://www.prelovac.com/vladimir/wordpress-plugins-rising-stars
|
32 |
+
|
33 |
+
= UpdraftPlus Addons And Premium =
|
34 |
+
|
35 |
+
UpdraftPlus is not crippled in any way - it is fully functional, with no annoying omissions. What we do have is various extra features, and guaranteed support, available <a href="http://updraftplus.com/">from our website, updraftplus.com</a>.
|
36 |
+
|
37 |
+
If you need WordPress multisite compatibility (you'll know if you do), <a href="http://updraftplus.com/shop/">then you need UpdraftPlus Premium</a>.
|
38 |
+
|
39 |
+
= Professional / Enterprise support agreements available =
|
40 |
+
|
41 |
+
UpdraftPlus is written by professional WordPress developers. If your site needs guaranteed support, then we are available. Just <a href="http://updraftplus.com/shop/">go to our shop.</a>
|
42 |
+
|
43 |
+
= Other support =
|
44 |
+
|
45 |
+
We hang out in the support forum for this plugin - http://wordpress.org/support/plugin/updraftplus - however, to save our time so that we can spend it on development, please read the plugin's Frequently Asked Questions - <a href="http://updraftplus.com/support/frequently-asked-questions/">http://updraftplus.com/support/frequently-asked-questions/</a> - before going there, and ensure that you have updated to the latest released version of UpdraftPlus.
|
46 |
+
|
47 |
+
== Installation ==
|
48 |
+
|
49 |
+
<a href="http://updraftplus.com/download/">Please go here for full instructions</a>.
|
50 |
+
|
51 |
+
== Frequently Asked Questions ==
|
52 |
+
|
53 |
+
<a href="http://updraftplus.com/support/frequently-asked-questions/"><strong>Please go here for the full FAQs.</strong></a> Below are just a handful which apply to the free wordpress.org version, or which bear repeating.
|
54 |
+
|
55 |
+
= Can UpdraftPlus do <something>? =
|
56 |
+
|
57 |
+
Check out <a href="http://updraftplus.com/updraftplus-full-feature-list/">our full list of features</a>, and our <a href="http://updraftplus.com/shop/">add-ons shop</a>.
|
58 |
+
|
59 |
+
= I found a bug. What do I do? =
|
60 |
+
|
61 |
+
Firstly, please make sure you read this FAQ through to the end - it may already have the answer you need. If it does, then please consider a donation (http://david.dw-perspective.org.uk/donate); it takes time to develop this plugin and FAQ.
|
62 |
+
|
63 |
+
If it does not, then contact me! This is a complex plugin and the only way I can ensure it's robust is to get bug reports and fix the problems that crop up. Please make sure you are using the latest version of the plugin, and that you include the version in your bug report - if you are not using the latest, then the first thing you will be asked to do is upgrade.
|
64 |
+
|
65 |
+
Please turn on debugging mode (in the UpdraftPlus options page) and then try again, and after that send me the log if you can find it (there are links to download logs on the UpdraftPlus settings page; or you may be emailed it; failing that, it is in the directory wp-content/updraft, so FTP in and look for it there). If you cannot find the log, then I may not be able to help so much, but you can try - include as much information as you can when reporting (PHP version, your blog's site, the error you saw and how you got to the page that caused it, etcetera).
|
66 |
+
|
67 |
+
If you know where to find your PHP error logs (often a file called error_log, possibly in your wp-admin directory (check via FTP)), then that's even better (don't send me multi-megabytes; just send the few lines that appear when you run a backup, if any).
|
68 |
+
|
69 |
+
If you are a programmer and can send a patch, then that's even better.
|
70 |
+
|
71 |
+
Finally, if you post in the WordPress support forum, then make sure you include the word UpdraftPlus in your post; otherwise I will not be automatically notified that you posted.
|
72 |
+
|
73 |
+
= Anything essential to know? =
|
74 |
+
|
75 |
+
After you have set up UpdraftPlus, you must check that your backups are taking place successfully. WordPress is a complex piece of software that runs in many situations. Don't wait until you need your backups before you find out that they never worked in the first place. Remember, there's no warranty and no guarantees - this is free software.
|
76 |
+
|
77 |
+
= My enormous website is hosted by a dirt-cheap provider who starve my account of resources, and UpdraftPlus runs out of time! Help! Please make UpdraftPlus deal with this situation so that I can save two dollars! =
|
78 |
+
|
79 |
+
UpdraftPlus supports resuming backup runs right from the beginning, so that it does not need to do everything in a single go; but this has limits. If your website is huge and your web hosting company gives your tiny resources on an over-loaded server, then your solution is to purchase better web hosting, or to hire me professionally. Otherwise, this is not considered a bug. UpdraftPlus is known to successfully back up websites that run into the gigabytes on web servers that are not resource-starved.
|
80 |
+
|
81 |
+
= How is this better than the original Updraft? =
|
82 |
+
|
83 |
+
You can check the changelog for changes; but the original Updraft, before I forked it, had three major problems. Firstly, it only backed up WP core tables from the database; if any of your plugins stored data in extra tables, then they were not backed up. Secondly, it only backed up your plugins/themes/uploads and not any further directories inside wp-content that other plugins might have created. Thirdly, the database backup did not include charset information, which meant that you needed to know some SQL wizardry to actually be able to use the backup. I made UpdraftPlus out of my experience of trying to back up several sites with Updraft. Then, I added encryption for the database file for extra peace of mind, and future-proofed by getting rid of some deprecated aspects. Since then, many new features have been added, e.g. resuming of failed uploads, and Dropbox support.
|
84 |
+
|
85 |
+
= Any known bugs ? =
|
86 |
+
|
87 |
+
Not a bug, but one issue to be aware of is that backups of very large sites (lots of uploaded media) are quite complex matters, given the limits of running inside WordPress on a huge variety of different web hosting setups. With large sites, you need to use Amazon S3, which UpdraftPlus supports (since 0.9.20) or Google Drive (since 0.9.21) or Dropbox (since 1.2.19), because these support chunked, resumable uploads. Other backup methods have code (since 0.9.0) to retry failed uploads of an archive, but the upload cannot be chunked, so if an archive is enormous (i.e. cannot be completely uploaded in the time that PHP is allowed for running on your web host) it cannot work.
|
88 |
+
|
89 |
+
= My site was hacked, and I have no backups! I thought UpdraftPlus was working! Can I kill you? =
|
90 |
+
|
91 |
+
No, there's no warranty or guarantee, etc. It's completely up to you to verify that UpdraftPlus is working correctly. If it doesn't then that's unfortunate, but this is a free plugin.
|
92 |
+
|
93 |
+
= I am not running the most recent version of UpdraftPlus. Should I upgrade? =
|
94 |
+
|
95 |
+
Yes; especially before you submit any support requests.
|
96 |
+
|
97 |
+
= Have you written any other free plugins? =
|
98 |
+
|
99 |
+
Thanks for asking - yes, I have. Check out my profile page - http://profiles.wordpress.org/DavidAnderson/ . I am also available for hire for bespoke work.
|
100 |
+
|
101 |
+
== Changelog ==
|
102 |
+
|
103 |
+
= 1.4.14 -02/19/2013 =
|
104 |
+
* Display final status message in email
|
105 |
+
|
106 |
+
= 1.4.13 - 02/18/2013 =
|
107 |
+
* Some extra hooks for "fix time" add-on (http://updraftplus.com/shop/fix-time/)
|
108 |
+
* Some internal simplification
|
109 |
+
* Small spelling + text fixes
|
110 |
+
|
111 |
+
= 1.4.11 - 02/13/2013 =
|
112 |
+
* Various branding tweaks - <a href="http://updraftplus.com">launch of updraftplus.com</a>
|
113 |
+
* Important fix for people with non-encrypted database backups
|
114 |
+
|
115 |
+
= 1.4.9 - 02/12/2013 =
|
116 |
+
* Do more when testing Amazon S3 connectivity (catches users with bucket but not file access)
|
117 |
+
* Tweak algorithm for detecting useful activity to further help gigantic sites
|
118 |
+
|
119 |
+
= 1.4.7 - 02/09/2013 =
|
120 |
+
* Tweak for some Amazon EU West 1 bucket users
|
121 |
+
|
122 |
+
= 1.4.6 - 02/07/2013 =
|
123 |
+
* Amazon S3 now works for users with non-US buckets
|
124 |
+
* Further tweak to overlap detection
|
125 |
+
|
126 |
+
= 1.4.2 - 02/06/2013 =
|
127 |
+
* More Amazon S3 logging which should help people with wrong details
|
128 |
+
* More race/overlap detection, and more flexible rescheduling
|
129 |
+
|
130 |
+
= 1.4.0 - 02/04/2013 =
|
131 |
+
* Zip file creation is now resumable; and thus the entire backup operation is; there is now no "too early to resume" point. So even the most enormous site backups should now be able to proceed.
|
132 |
+
* Prefer PHP's native zip functions if available - 25% speed-up on zip creation
|
133 |
+
|
134 |
+
= 1.3.22 - 01/31/2013 =
|
135 |
+
* More help for really large uploads; dynamically alter the maximum number of resumption attempts if something useful is still happening
|
136 |
+
|
137 |
+
= 1.3.20 - 01/30/2013 =
|
138 |
+
* Add extra error checking in S3 method (can prevent logging loop)
|
139 |
+
|
140 |
+
= 1.3.19 - 01/29/2013 =
|
141 |
+
* Since 1.3.3, the 'Last Backup' indicator in the control panel had not been updating
|
142 |
+
|
143 |
+
= 1.3.18 - 01/28/2013 =
|
144 |
+
* Made 'expert mode' easier to operate, and tidier options for non-expert users.
|
145 |
+
* Some (not total) compliance with PHP's strict coding standards mode
|
146 |
+
* More detail provided when failing to authorise with Google
|
147 |
+
|
148 |
+
= 1.3.15 - 01/26/2013 =
|
149 |
+
* Various changes to Google Drive authentication to help those who don't enter the correct details first time, or who later need to change accounts.
|
150 |
+
|
151 |
+
= 1.3.12 - 01/25/2013 =
|
152 |
+
* 1.3.0 to 1.3.8 had a fatal flaw for people with large backups.
|
153 |
+
* 1.3.0 to 1.3.9 gave erroneous information in the email reports on what the backup contained.
|
154 |
+
* Fixed DropBox authentication for some users who were having problems
|
155 |
+
|
156 |
+
= 1.3.8 - 01/24/2013 =
|
157 |
+
* Fixed faulty assumptions in 'resume' code, now leading to more reliable resuming
|
158 |
+
* Removed some duplicate code; first attempt and resumptions now uses same code
|
159 |
+
* Added further parameters that should be removed on a wipe operation
|
160 |
+
* More logging of detected double runs
|
161 |
+
|
162 |
+
= 1.3.2 - 01/23/2013 =
|
163 |
+
* Internal reorganisation, enabling UpdraftPlus Premium
|
164 |
+
|
165 |
+
= 1.2.46 - 01/22/2013 =
|
166 |
+
* Easier Dropbox setup (we are now an official production app)
|
167 |
+
* New button to delete all existing settings
|
168 |
+
* Admin console now displays rolling status updates
|
169 |
+
* Feature: choose how many files and databases to retain separately
|
170 |
+
* Fixed bug with checking access token on Google Drive restore
|
171 |
+
* Fixed bug producing copious warnings in PHP log
|
172 |
+
* Fixed bug in automated restoration processes
|
173 |
+
* Possibly fixed settings saving bug in RTL installations
|
174 |
+
* Fix erroneous display of max_execution_time warning
|
175 |
+
* Better logging when running a DB debug session
|
176 |
+
* Better detection/handling of overlapping/concurrent runs
|
177 |
+
|
178 |
+
= 1.2.31 - 01/15/2013 =
|
179 |
+
* Fixed bug with Dropbox deletions
|
180 |
+
* Fixed cases where Dropbox failed to resume chunked uploading
|
181 |
+
* Can now create uncreated zip files on a resumption attempt
|
182 |
+
* FTP method now supports SSL (automatically detected)
|
183 |
+
* New "Test FTP settings" button
|
184 |
+
* Less noise when debugging is turned off
|
185 |
+
* Fix bug (in 1.2.30) that prevented some database uploads completing
|
186 |
+
|
187 |
+
= 1.2.20 - 01/12/2013 =
|
188 |
+
* Dropbox no longer limited to 150Mb uploads
|
189 |
+
* Dropbox can upload in chunks and resume uploading chunks
|
190 |
+
* Improved Dropbox help text
|
191 |
+
|
192 |
+
= 1.2.18 - 01/11/2013 =
|
193 |
+
* Revert Dropbox to CURL-only - was not working properly with WordPress's built-in methods
|
194 |
+
* Add note that only up to 150Mb is possible for a Dropbox upload, until we change our API usage
|
195 |
+
* Fix unnecessary repetition of database dump upon resumption of a failed backup
|
196 |
+
|
197 |
+
= 1.2.14 - 01/08/2013 =
|
198 |
+
* Dropbox support (no chunked uploading yet, but otherwise complete)
|
199 |
+
* Make the creation of the database dump also resumable, for people with really slow servers
|
200 |
+
* Database table backups are now timed
|
201 |
+
* FTP logging slightly improved
|
202 |
+
* Dropbox support uses WordPress's built-in HTTP functions
|
203 |
+
|
204 |
+
= 1.1.16 - 01/07/2013 =
|
205 |
+
* Requested feature: more frequent scheduling options requested
|
206 |
+
* Fixed bug which mangled default suggestion for backup working directory on Windows
|
207 |
+
* Provide a 'Test S3 Settings' button for Amazon S3 users
|
208 |
+
|
209 |
+
= 1.1.11 - 01/04/2013 =
|
210 |
+
* Bug fix: some backup runs were erroneously being identified as superfluous and cancelled
|
211 |
+
|
212 |
+
= 1.1.9 - 12/31/2012 =
|
213 |
+
* Big code re-factoring; cloud access methods now modularised, paving way for easier adding of new methods. Note that Google Drive users may need to re-authenticate - please check that your backups are working.
|
214 |
+
* Fix bug whereby some resumptions of failed backups were erroneously cancelled
|
215 |
+
* Database encryption made part of what is resumable
|
216 |
+
|
217 |
+
= 1.0.16 - 12/24/2012 =
|
218 |
+
* Improve race detection and clean up already-created files when detected
|
219 |
+
|
220 |
+
= 1.0.15 - 12/22/2012 =
|
221 |
+
* Fixed bug that set 1Tb (instead of 1Mb) chunk sizes for Google Drive uploads
|
222 |
+
* Added link to some screenshots to help with Google Drive setup
|
223 |
+
* Allowed use of existing Amazon S3 buckets with restrictive policies (previously, we tested for the bucket's existence by running a create operation on it, which may not be permitted)
|
224 |
+
* Use WordPress's native HTTP functions for greater reliability when performing Google Drive authorisation
|
225 |
+
* Deal with WP-Cron racey double events (abort superceeded backups)
|
226 |
+
* Allow user to download logs from admin interface
|
227 |
+
|
228 |
+
= 1.0.5 - 12/13/2012 =
|
229 |
+
* Tweaked default Google Drive options
|
230 |
+
|
231 |
+
= 1.0.4 - 12/10/2012 =
|
232 |
+
* Implemented resumption/chunked uploading on Google Drive - much bigger sites can now be backed up
|
233 |
+
* Fixed bug whereby setting for deleting local backups was lost
|
234 |
+
* Now marked as 1.0, since we are feature-complete with targeted features for this release
|
235 |
+
* Made description fuller
|
236 |
+
|
237 |
+
= 0.9.20 - 12/06/2012 =
|
238 |
+
* Updated to latest S3.php library with chunked uploading patch
|
239 |
+
* Implemented chunked uploading on Amazon S3 - much bigger sites can now be backed up with S3
|
240 |
+
|
241 |
+
= 0.9.10 - 11/22/2012 =
|
242 |
+
* Completed basic Google Drive support (thanks to Sorin Iclanzan, code taken from "Backup" plugin under GPLv3+); now supporting uploading, purging and restoring - i.e. full UpdraftPlus functionality
|
243 |
+
* Licence change to GPLv3+ (from GPLv2+) to allow incorporating Sorin's code
|
244 |
+
* Tidied/organised the settings screen further
|
245 |
+
|
246 |
+
= 0.9.2 - 11/21/2012 =
|
247 |
+
* Failed uploads can now be re-tried, giving really big blogs a better opportunity to eventually succeed uploading
|
248 |
+
|
249 |
+
= 0.8.51 - 11/19/2012 =
|
250 |
+
* Moved screenshot into assets, reducing plugin download size
|
251 |
+
|
252 |
+
= 0.8.50 - 10/13/2012 =
|
253 |
+
* Important new feature: back up other directories found in the WP content (wp-content) directory (not just plugins/themes/uploads, as in original Updraft)
|
254 |
+
|
255 |
+
= 0.8.37 - 10/12/2012 =
|
256 |
+
* Don't whinge about Google Drive authentication if that method is not current
|
257 |
+
|
258 |
+
= 0.8.36 - 10/03/2012 =
|
259 |
+
* Support using sub-directories in Amazon S3
|
260 |
+
* Some more debug logging for Amazon S3
|
261 |
+
|
262 |
+
= 0.8.33 - 09/19/2012 =
|
263 |
+
* Work around some web hosts with invalid safe_mode configurations
|
264 |
+
|
265 |
+
= 0.8.32 - 09/17/2012 =
|
266 |
+
* Fix a subtle bug that caused database tables from outside of this WordPress install to be backed up
|
267 |
+
|
268 |
+
= 0.8.31 - 09/08/2012 =
|
269 |
+
* Fixed error deleting old S3 backups. If your expired S3 backups were not deleted, they should be in future - but you will need to delete manually those that expired before you installed this update.
|
270 |
+
* Fixed minor bug closing log file
|
271 |
+
* Marked as working with WordPress 3.4.2
|
272 |
+
|
273 |
+
= 0.8.29 - 06/29/2012 =
|
274 |
+
* Marking as tested up to WordPress 3.4.1
|
275 |
+
|
276 |
+
= 0.8.28 - 06/06/2012 =
|
277 |
+
* Now experimentally supports Google Drive (thanks to Sorin Iclanzan, code re-used from his Google Drive-only 'backup' plugin)
|
278 |
+
* New feature: backup files and database on separate schedules
|
279 |
+
* Tidied and improved retain behaviour
|
280 |
+
|
281 |
+
= 0.7.7 - 05/29/2012 =
|
282 |
+
* Implementation of a logging mechanism to allow easier debugging and development
|
283 |
+
|
284 |
+
= 0.7.4 - 05/21/2012 =
|
285 |
+
* Removed CloudFront method; I have no way of testing this
|
286 |
+
* Backup all tables found in the database that have this site's table prefix
|
287 |
+
* If encryption fails, then abort (don't revert to not encrypting)
|
288 |
+
* Added ability to decrypt encrypted database backups
|
289 |
+
* Added ability to opt out of backing up each file group
|
290 |
+
* Now adds database character set, the lack of which before made database backups unusable without modifications
|
291 |
+
* Version number bump to make clear that this is an improvement on the original Updraft, and is now tried and tested
|
292 |
+
|
293 |
+
= 0.1.3 - 01/16/2012 =
|
294 |
+
* Force backup of all tables found in database (vanilla Updraft only backed up WP core tables)
|
295 |
+
* Tweak notification email to include site name
|
296 |
+
|
297 |
+
= 0.1 - 08/10/2011 =
|
298 |
+
|
299 |
+
* A fork of Updraft 0.6.1 by Paul Kehrer with the following improvements
|
300 |
+
* Replaced deprecated function calls (in WordPress 3.2.1)
|
301 |
+
* Removed all warnings from basic admin page with WP_DEBUG on
|
302 |
+
* Implemented encrypted backup (but not yet automatic restoration) on database
|
303 |
+
* Some de-uglification of admin interface
|
304 |
+
|
305 |
+
|
306 |
+
== Screenshots ==
|
307 |
+
|
308 |
+
1. Configuration page
|
309 |
+
|
310 |
+
We recognise and thank the following for code and/or libraries used and/or modified under the terms of their licences:
|
311 |
+
* UpdraftPlus is based on the original Updraft by Paul Kehrer (Twitter: http://twitter.com/reaperhulk, Blog: http://langui.sh)
|
312 |
+
* Sorin Iclanzan, http://profiles.wordpress.org/hel.io/
|
313 |
+
* Ben Tadiar, https://github.com/BenTheDesigner/Dropbox
|
314 |
+
* Beau Brownlee, http://www.solutionbot.com/2009/01/02/php-ftp-class/
|
315 |
+
* Donovan Schonknecht, http://undesigned.org.za/2007/10/22/amazon-s3-php-class
|
316 |
+
|
317 |
+
== License ==
|
318 |
+
|
319 |
+
Portions copyright 2011-3 David Anderson
|
320 |
+
Portions copyright 2010 Paul Kehrer
|
321 |
+
|
322 |
+
This program is free software; you can redistribute it and/or modify
|
323 |
+
it under the terms of the GNU General Public License as published by
|
324 |
+
the Free Software Foundation; either version 2 of the License, or
|
325 |
+
(at your option) any later version.
|
326 |
+
|
327 |
+
This program is distributed in the hope that it will be useful,
|
328 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
329 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
330 |
+
GNU General Public License for more details.
|
331 |
+
|
332 |
+
You should have received a copy of the GNU General Public License
|
333 |
+
along with this program; if not, write to the Free Software
|
334 |
+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
335 |
+
|
trunk/updraftplus.php
ADDED
@@ -0,0 +1,2441 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Plugin Name: UpdraftPlus - Backup/Restore
|
4 |
+
Plugin URI: http://updraftplus.com
|
5 |
+
Description: Backup and restore: your content and database can be automatically backed up to Amazon S3, Dropbox, Google Drive, FTP or email, on separate schedules.
|
6 |
+
Author: David Anderson
|
7 |
+
Version: 1.4.14
|
8 |
+
Donate link: http://david.dw-perspective.org.uk/donate
|
9 |
+
License: GPLv3 or later
|
10 |
+
Author URI: http://wordshell.net
|
11 |
+
*/
|
12 |
+
|
13 |
+
/*
|
14 |
+
TODO
|
15 |
+
//Put in old-WP-version warning, and point them to where they can get help
|
16 |
+
//Add SFTP, Box.Net, SugarSync and Microsoft Skydrive support??
|
17 |
+
//The restorer has a hard-coded wp-content - fix
|
18 |
+
//Button for wiping files. Also auto-wipe on de-activate/de-install.
|
19 |
+
//Change DB encryption to not require whole gzip in memory (twice)
|
20 |
+
//improve error reporting / pretty up return messages in admin area. One thing: have a "backup is now finished" flag. Otherwise with the resuming things get ambiguous/confusing. See http://wordpress.org/support/topic/backup-status - user was not aware that backup completely failed. Maybe a "backup status" field for each nonce that gets updated? (Even via AJAX?)
|
21 |
+
//?? On 'backup now', open up a Lightbox, count down 5 seconds, then start examining the log file (if it can be found)
|
22 |
+
//Should make clear in dashboard what is a non-fatal error (i.e. can be retried) - leads to unnecessary bug reports
|
23 |
+
// Move the inclusion, cloud and retention data into the backup job (i.e. don't read current config, make it an attribute of each job). In fact, everything should be. So audit all code for where get_option is called inside a backup run: it shouldn't happen.
|
24 |
+
// Should we resume if the only errors were upon deletion (i.e. the backup itself was fine?) Presently we do, but it displays errors for the user to confuse them. Perhaps better to make pruning a separate scheuled task??
|
25 |
+
// Warn the user if their zip-file creation is slooowww...
|
26 |
+
// Create a "Want Support?" button/console, that leads them through what is needed, and performs some basic tests...
|
27 |
+
// Resuming partial FTP uploads
|
28 |
+
// Provide backup/restoration for UpdraftPlus's settings, to allow 'bootstrap' on a fresh WP install - some kind of single-use code which a remote UpdraftPlus can use to authenticate
|
29 |
+
// Multiple jobs
|
30 |
+
// Change FTP to use SSL by default
|
31 |
+
// Multisite add-on should allow restoring of each blog individually
|
32 |
+
// When looking for files to delete, is the current encryption setting used? Should not be.
|
33 |
+
// Create single zip, containing even WordPress itself
|
34 |
+
// Have something reap any remaining .tmp files, e.g. once a week
|
35 |
+
// When a new backup starts, AJAX-update the 'Last backup' display in the admin page.
|
36 |
+
// Remove the recurrence of admin notices when settings are saved due to _wp_referer
|
37 |
+
// Auto-detect what the real execution time is (max_execution_time is just one of the upper limits, there can be others, some insivible directly), and tweak our resumption time accordingly
|
38 |
+
//http://w-shadow.com/blog/2010/09/02/automatic-updates-for-any-plugin/
|
39 |
+
// Specify the exact time to run the backup (useful if you have big site, using a lot of CPU)
|
40 |
+
|
41 |
+
Encrypt filesystem, if memory allows (and have option for abort if not); split up into multiple zips when needed
|
42 |
+
// Does not delete old custom directories upon a restore?
|
43 |
+
// Re-do making of zip files to allow resumption (every x files, store the state in a transient)
|
44 |
+
// New sub-module to verify that the backups are there, independently of backup thread
|
45 |
+
*/
|
46 |
+
|
47 |
+
/* Portions copyright 2010 Paul Kehrer
|
48 |
+
Portions copyright 2011-12 David Anderson
|
49 |
+
Other portions copyright as indicated authors in the relevant files
|
50 |
+
Particular thanks to Sorin Iclanzan, author of the "Backup" plugin, from which much Google Drive code was taken under the GPLv3+
|
51 |
+
|
52 |
+
This program is free software; you can redistribute it and/or modify
|
53 |
+
it under the terms of the GNU General Public License as published by
|
54 |
+
the Free Software Foundation; either version 3 of the License, or
|
55 |
+
(at your option) any later version.
|
56 |
+
|
57 |
+
This program is distributed in the hope that it will be useful,
|
58 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
59 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
60 |
+
GNU General Public License for more details.
|
61 |
+
|
62 |
+
You should have received a copy of the GNU General Public License
|
63 |
+
along with this program; if not, write to the Free Software
|
64 |
+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
65 |
+
*/
|
66 |
+
|
67 |
+
// 15 minutes
|
68 |
+
@set_time_limit(900);
|
69 |
+
|
70 |
+
define('UPDRAFTPLUS_DIR', dirname(__FILE__));
|
71 |
+
define('UPDRAFTPLUS_URL', plugins_url('', __FILE__));
|
72 |
+
define('UPDRAFT_DEFAULT_OTHERS_EXCLUDE','upgrade,cache,updraft,index.php,backup,backups');
|
73 |
+
// This is used in various places, based on our assumption of the maximum time any job should take. May need lengthening in future if we get reports which show enormous sets hitting the limit.
|
74 |
+
// Also one section requires at least 1% progress each run, so on a 5-minute schedule, that equals just under 9 hours - then an extra allowance takes it just over
|
75 |
+
define('UPDRAFT_TRANSTIME', 3600*9+5);
|
76 |
+
|
77 |
+
// Load add-ons
|
78 |
+
if (is_file(UPDRAFTPLUS_DIR.'/premium.php')) require_once(UPDRAFTPLUS_DIR.'/premium.php');
|
79 |
+
|
80 |
+
if ($dir_handle = opendir(UPDRAFTPLUS_DIR.'/addons')) {
|
81 |
+
while ($e = readdir($dir_handle)) {
|
82 |
+
if (is_file(UPDRAFTPLUS_DIR.'/addons/'.$e) && preg_match('/\.php$/', $e)) {
|
83 |
+
include_once(UPDRAFTPLUS_DIR.'/addons/'.$e);
|
84 |
+
}
|
85 |
+
}
|
86 |
+
@closedir($dir_handle);
|
87 |
+
}
|
88 |
+
|
89 |
+
if (!isset($updraftplus)) $updraftplus = new UpdraftPlus();
|
90 |
+
|
91 |
+
if (!$updraftplus->memory_check(192)) {
|
92 |
+
# TODO: Better solution is to split the backup set into manageable chunks based on this limit
|
93 |
+
@ini_set('memory_limit', '192M'); //up the memory limit for large backup files
|
94 |
+
}
|
95 |
+
|
96 |
+
if (!class_exists('UpdraftPlus_Options')) require_once(UPDRAFTPLUS_DIR.'/options.php');
|
97 |
+
|
98 |
+
class UpdraftPlus {
|
99 |
+
|
100 |
+
var $version;
|
101 |
+
|
102 |
+
var $plugin_title = 'UpdraftPlus Backup/Restore';
|
103 |
+
|
104 |
+
// Choices will be shown in the admin menu in the order used here
|
105 |
+
var $backup_methods = array (
|
106 |
+
"s3" => "Amazon S3",
|
107 |
+
"dropbox" => "Dropbox",
|
108 |
+
"googledrive" => "Google Drive",
|
109 |
+
"ftp" => "FTP",
|
110 |
+
"email" => "Email"
|
111 |
+
);
|
112 |
+
|
113 |
+
var $dbhandle;
|
114 |
+
var $dbhandle_isgz;
|
115 |
+
var $errors = array();
|
116 |
+
var $nonce;
|
117 |
+
var $logfile_name = "";
|
118 |
+
var $logfile_handle = false;
|
119 |
+
var $backup_time;
|
120 |
+
|
121 |
+
var $opened_log_time;
|
122 |
+
var $backup_dir;
|
123 |
+
|
124 |
+
var $jobdata;
|
125 |
+
|
126 |
+
// Used to schedule resumption attempts beyond the tenth, if needed
|
127 |
+
var $current_resumption;
|
128 |
+
var $newresumption_scheduled = false;
|
129 |
+
|
130 |
+
var $zipfiles_added;
|
131 |
+
var $zipfiles_existingfiles;
|
132 |
+
var $zipfiles_dirbatched;
|
133 |
+
var $zipfiles_batched;
|
134 |
+
|
135 |
+
var $zip_preferpcl = false;
|
136 |
+
|
137 |
+
function __construct() {
|
138 |
+
|
139 |
+
// Initialisation actions - takes place on plugin load
|
140 |
+
|
141 |
+
if ($fp = fopen( __FILE__, 'r')) {
|
142 |
+
$file_data = fread( $fp, 1024 );
|
143 |
+
if (preg_match("/Version: ([\d\.]+)(\r|\n)/", $file_data, $matches)) {
|
144 |
+
$this->version = $matches[1];
|
145 |
+
}
|
146 |
+
fclose( $fp );
|
147 |
+
}
|
148 |
+
|
149 |
+
# Create admin page
|
150 |
+
add_action('admin_init', array($this, 'admin_init'));
|
151 |
+
add_action('updraft_backup', array($this,'backup_files'));
|
152 |
+
add_action('updraft_backup_database', array($this,'backup_database'));
|
153 |
+
# backup_all is used by the manual "Backup Now" button
|
154 |
+
add_action('updraft_backup_all', array($this,'backup_all'));
|
155 |
+
# this is our runs-after-backup event, whose purpose is to see if it succeeded or failed, and resume/mom-up etc.
|
156 |
+
add_action('updraft_backup_resume', array($this,'backup_resume'), 10, 3);
|
157 |
+
add_action('wp_ajax_updraft_download_backup', array($this, 'updraft_download_backup'));
|
158 |
+
add_action('wp_ajax_updraft_ajax', array($this, 'updraft_ajax_handler'));
|
159 |
+
# http://codex.wordpress.org/Plugin_API/Filter_Reference/cron_schedules
|
160 |
+
add_filter('cron_schedules', array($this,'modify_cron_schedules'));
|
161 |
+
add_filter('plugin_action_links', array($this, 'plugin_action_links'), 10, 2);
|
162 |
+
add_action('init', array($this, 'handle_url_actions'));
|
163 |
+
|
164 |
+
}
|
165 |
+
|
166 |
+
// Handle actions passed on to method plugins; e.g. Google OAuth 2.0 - ?page=updraftplus&action=updraftmethod-googledrive-auth
|
167 |
+
// Also handle action=downloadlog
|
168 |
+
function handle_url_actions() {
|
169 |
+
// First, basic security check: must be an admin page, with ability to manage options, with the right parameters
|
170 |
+
if ( UpdraftPlus_Options::user_can_manage() && isset( $_GET['page'] ) && $_GET['page'] == 'updraftplus' && isset($_GET['action']) ) {
|
171 |
+
if (preg_match("/^updraftmethod-([a-z]+)-([a-z]+)$/", $_GET['action'], $matches) && file_exists(UPDRAFTPLUS_DIR.'/methods/'.$matches[1].'.php')) {
|
172 |
+
$method = $matches[1];
|
173 |
+
require_once(UPDRAFTPLUS_DIR.'/methods/'.$method.'.php');
|
174 |
+
$call_class = "UpdraftPlus_BackupModule_".$method;
|
175 |
+
$call_method = "action_".$matches[2];
|
176 |
+
if (method_exists($call_class, $call_method)) call_user_func(array($call_class,$call_method));
|
177 |
+
} elseif ($_GET['action'] == 'downloadlog' && isset($_GET['updraftplus_backup_nonce']) && preg_match("/^[0-9a-f]{12}$/",$_GET['updraftplus_backup_nonce'])) {
|
178 |
+
$updraft_dir = $this->backups_dir_location();
|
179 |
+
$log_file = $updraft_dir.'/log.'.$_GET['updraftplus_backup_nonce'].'.txt';
|
180 |
+
if (is_readable($log_file)) {
|
181 |
+
header('Content-type: text/plain');
|
182 |
+
readfile($log_file);
|
183 |
+
exit;
|
184 |
+
} else {
|
185 |
+
add_action('admin_notices', array($this,'show_admin_warning_unreadablelog') );
|
186 |
+
}
|
187 |
+
}
|
188 |
+
}
|
189 |
+
}
|
190 |
+
|
191 |
+
// Cleans up temporary files found in the updraft directory
|
192 |
+
function clean_temporary_files() {
|
193 |
+
$updraft_dir = $this->backups_dir_location();
|
194 |
+
if ($handle = opendir($updraft_dir)) {
|
195 |
+
$now_time=time();
|
196 |
+
while (false !== ($entry = readdir($handle))) {
|
197 |
+
if (preg_match('/\.tmp(\.gz)?$/', $entry) && is_file($updraft_dir.'/'.$entry) && $now_time-filemtime($updraft_dir.'/'.$entry)>86400) {
|
198 |
+
$this->log("Deleting old temporary file: $entry");
|
199 |
+
@unlink($updraft_dir.'/'.$entry);
|
200 |
+
}
|
201 |
+
}
|
202 |
+
@closedir($handle);
|
203 |
+
}
|
204 |
+
}
|
205 |
+
|
206 |
+
# Adds the settings link under the plugin on the plugin screen.
|
207 |
+
function plugin_action_links($links, $file) {
|
208 |
+
if ($file == plugin_basename(__FILE__)){
|
209 |
+
$settings_link = '<a href="'.site_url().'/wp-admin/options-general.php?page=updraftplus">'.__("Settings", "UpdraftPlus").'</a>';
|
210 |
+
array_unshift($links, $settings_link);
|
211 |
+
$settings_link = '<a href="http://david.dw-perspective.org.uk/donate">'.__("Donate","UpdraftPlus").'</a>';
|
212 |
+
array_unshift($links, $settings_link);
|
213 |
+
$settings_link = '<a href="http://updraftplus.com">'.__("Add-Ons / Pro Support","UpdraftPlus").'</a>';
|
214 |
+
array_unshift($links, $settings_link);
|
215 |
+
}
|
216 |
+
return $links;
|
217 |
+
}
|
218 |
+
|
219 |
+
function backup_time_nonce() {
|
220 |
+
$this->backup_time = time();
|
221 |
+
$nonce = substr(md5(time().rand()), 20);
|
222 |
+
$this->nonce = $nonce;
|
223 |
+
}
|
224 |
+
|
225 |
+
function logfile_open($nonce) {
|
226 |
+
//set log file name and open log file
|
227 |
+
$updraft_dir = $this->backups_dir_location();
|
228 |
+
$this->logfile_name = $updraft_dir. "/log.$nonce.txt";
|
229 |
+
// Use append mode in case it already exists
|
230 |
+
$this->logfile_handle = fopen($this->logfile_name, 'a');
|
231 |
+
$this->opened_log_time = microtime(true);
|
232 |
+
$this->log("Opened log file at time: ".date('r'));
|
233 |
+
global $wp_version;
|
234 |
+
$logline = "UpdraftPlus: ".$this->version." WordPress: ".$wp_version." PHP: ".phpversion()." (".php_uname().") PHP Max Execution Time: ".@ini_get("max_execution_time")." ZipArchive::addFile exists: ";
|
235 |
+
// method_exists causes some faulty PHP installations to segfault, leading to support requests
|
236 |
+
if (version_compare(phpversion(), '5.2.0', '>=') && extension_loaded('zip')) {
|
237 |
+
$logline .= 'Y';
|
238 |
+
} else {
|
239 |
+
$logline .= (method_exists('ZipArchive', 'addFile')) ? "Y" : "N";
|
240 |
+
}
|
241 |
+
$this->log($logline);
|
242 |
+
}
|
243 |
+
|
244 |
+
# Logs the given line, adding (relative) time stamp and newline
|
245 |
+
function log($line) {
|
246 |
+
if ($this->logfile_handle) fwrite($this->logfile_handle, sprintf("%08.03f", round(microtime(true)-$this->opened_log_time, 3))." ".$line."\n");
|
247 |
+
UpdraftPlus_Options::update_updraft_option("updraft_lastmessage", $line." (".date('M d H:i:s').")");
|
248 |
+
}
|
249 |
+
|
250 |
+
// This function is used by cloud methods to provide standardised logging, but more importantly to help us detect that meaningful activity took place during a resumption run, so that we can schedule further resumptions if it is worthwhile
|
251 |
+
function record_uploaded_chunk($percent, $extra) {
|
252 |
+
// Log it
|
253 |
+
$service = $this->jobdata_get('service');
|
254 |
+
$log = ucfirst($service)." chunked upload: $percent % uploaded";
|
255 |
+
if ($extra) $log .= " ($extra)";
|
256 |
+
$this->log($log);
|
257 |
+
// If we are on an 'overtime' resumption run, and we are still meainingfully uploading, then schedule a new resumption
|
258 |
+
// Our definition of meaningful is that we must maintain an overall average of at least 1% per run, after allowing 9 runs for everything else to get going
|
259 |
+
// i.e. Max 109 runs = 545 minutes = 9 hrs 05
|
260 |
+
// If they get 2 minutes on each run, and the file is 1Gb, then that equals 10.2Mb/120s = minimum 87Kb/s upload speed required
|
261 |
+
|
262 |
+
if ($this->current_resumption >= 9 && $this->newresumption_scheduled == false && $percent > ( $this->current_resumption - 9)) {
|
263 |
+
$resume_interval = $this->jobdata_get('resume_interval');
|
264 |
+
if (!is_numeric($resume_interval) || $resume_interval<200) { $resume_interval = 200; }
|
265 |
+
$schedule_for = time()+$resume_interval;
|
266 |
+
$this->newresumption_scheduled = $schedule_for;
|
267 |
+
$this->log("This is resumption ".$this->current_resumption.", but meaningful uploading is still taking place; so a new one will be scheduled");
|
268 |
+
wp_schedule_single_event($schedule_for, 'updraft_backup_resume', array($this->current_resumption + 1, $this->nonce));
|
269 |
+
}
|
270 |
+
}
|
271 |
+
|
272 |
+
function backup_resume($resumption_no, $bnonce) {
|
273 |
+
|
274 |
+
@ignore_user_abort(true);
|
275 |
+
// This is scheduled for 5 minutes after a backup job starts
|
276 |
+
|
277 |
+
// Restore state
|
278 |
+
if ($resumption_no > 0) {
|
279 |
+
$this->nonce = $bnonce;
|
280 |
+
$this->backup_time = $this->jobdata_get('backup_time');
|
281 |
+
$this->logfile_open($bnonce);
|
282 |
+
}
|
283 |
+
|
284 |
+
$btime = $this->backup_time;
|
285 |
+
|
286 |
+
$this->log("Backup run: resumption=$resumption_no, nonce=$bnonce, begun at=$btime");
|
287 |
+
$this->current_resumption = $resumption_no;
|
288 |
+
|
289 |
+
// Schedule again, to run in 5 minutes again, in case we again fail
|
290 |
+
// The actual interval can be increased (for future resumptions) by other code, if it detects apparent overlapping
|
291 |
+
$resume_interval = $this->jobdata_get('resume_interval');
|
292 |
+
if (!is_numeric($resume_interval) || $resume_interval<200) $resume_interval = 200;
|
293 |
+
|
294 |
+
// A different argument than before is needed otherwise the event is ignored
|
295 |
+
$next_resumption = $resumption_no+1;
|
296 |
+
if ($next_resumption < 10) {
|
297 |
+
$this->log("Scheduling a resumption ($next_resumption) in case this run gets aborted");
|
298 |
+
$schedule_for = time()+$resume_interval;
|
299 |
+
wp_schedule_single_event($schedule_for, 'updraft_backup_resume', array($next_resumption, $bnonce));
|
300 |
+
$this->newresumption_scheduled = $schedule_for;
|
301 |
+
} else {
|
302 |
+
$this->log("The current run is our tenth attempt - will not schedule a further attempt until we see something useful happening");
|
303 |
+
}
|
304 |
+
|
305 |
+
// This should be always called; if there were no files in this run, it returns us an empty array
|
306 |
+
$backup_array = $this->resumable_backup_of_files($resumption_no);
|
307 |
+
// This save, if there was something, is then immediately picked up again
|
308 |
+
if (is_array($backup_array)) $this->save_backup_history($backup_array);
|
309 |
+
|
310 |
+
// Returns an array, most recent first, of backup sets
|
311 |
+
$backup_history = $this->get_backup_history();
|
312 |
+
if (!isset($backup_history[$btime])) {
|
313 |
+
$this->log("Could not find a record in the database of a backup with this timestamp");
|
314 |
+
}
|
315 |
+
|
316 |
+
$our_files=$backup_history[$btime];
|
317 |
+
if (!is_array($our_files)) $our_files = array();
|
318 |
+
|
319 |
+
$undone_files = array();
|
320 |
+
|
321 |
+
$backup_database = $this->jobdata_get('backup_database');
|
322 |
+
|
323 |
+
// The transient is read and written below (instead of using the existing variable) so that we can copy-and-paste this part as needed.
|
324 |
+
if ($backup_database == "begun" || $backup_database == 'finished' || $backup_database == 'encrypted') {
|
325 |
+
if ($backup_database == "begun") {
|
326 |
+
if ($resumption_no > 0) {
|
327 |
+
$this->log("Resuming creation of database dump");
|
328 |
+
} else {
|
329 |
+
$this->log("Beginning creation of database dump");
|
330 |
+
}
|
331 |
+
} elseif ($backup_database == 'encrypted') {
|
332 |
+
$this->log("Database dump: Creation and encryption were completed already");
|
333 |
+
} else {
|
334 |
+
$this->log("Database dump: Creation was completed already");
|
335 |
+
}
|
336 |
+
$db_backup = $this->backup_db($backup_database);
|
337 |
+
if(is_array($our_files) && is_string($db_backup)) $our_files['db'] = $db_backup;
|
338 |
+
if ($backup_database != 'encrypted') $this->jobdata_set("backup_database", 'finished');
|
339 |
+
} else {
|
340 |
+
$this->log("Unrecognised data when trying to ascertain if the database was backed up ($backup_database)");
|
341 |
+
}
|
342 |
+
|
343 |
+
// Save this to our history so we can track backups for the retain feature
|
344 |
+
$this->log("Saving backup history");
|
345 |
+
// This is done before cloud despatch, because we want a record of what *should* be in the backup. Whether it actually makes it there or not is not yet known.
|
346 |
+
$this->save_backup_history($our_files);
|
347 |
+
|
348 |
+
// Potentially encrypt the database if it is not already
|
349 |
+
if (isset($our_files['db']) && !preg_match("/\.crypt$/", $our_files['db'])) {
|
350 |
+
$our_files['db'] = $this->encrypt_file($our_files['db']);
|
351 |
+
$this->save_backup_history($our_files);
|
352 |
+
if (preg_match("/\.crypt$/", $our_files['db'])) $this->jobdata_set("backup_database", 'encrypted');
|
353 |
+
}
|
354 |
+
|
355 |
+
foreach ($our_files as $key => $file) {
|
356 |
+
|
357 |
+
// Only continue if the stored info was about a dump
|
358 |
+
if ($key != 'plugins' && $key != 'themes' && $key != 'others' && $key != 'uploads' && $key != 'db') continue;
|
359 |
+
|
360 |
+
$hash = md5($file);
|
361 |
+
$fullpath = $this->backups_dir_location().'/'.$file;
|
362 |
+
if ($this->jobdata_get("uploaded_$hash") === "yes") {
|
363 |
+
$this->log("$file: $key: This file has already been successfully uploaded");
|
364 |
+
} elseif (is_file($fullpath)) {
|
365 |
+
$this->log("$file: $key: This file has not yet been successfully uploaded: will queue");
|
366 |
+
$undone_files[$key] = $file;
|
367 |
+
} else {
|
368 |
+
$this->log("$file: Note: This file was not marked as successfully uploaded, but does not exist on the local filesystem");
|
369 |
+
$this->uploaded_file($file);
|
370 |
+
}
|
371 |
+
}
|
372 |
+
|
373 |
+
if (count($undone_files) == 0) {
|
374 |
+
$this->log("There were no more files that needed uploading; backup job is complete");
|
375 |
+
// No email, as the user probably already got one if something else completed the run
|
376 |
+
$this->backup_finish($next_resumption, true, false, $resumption_no);
|
377 |
+
return;
|
378 |
+
}
|
379 |
+
|
380 |
+
$this->log("Requesting backup of the files that were not successfully uploaded");
|
381 |
+
$this->cloud_backup($undone_files);
|
382 |
+
|
383 |
+
$this->log("Resume backup ($bnonce, $resumption_no): finish run");
|
384 |
+
if (is_array($our_files)) $this->save_last_backup($our_files);
|
385 |
+
$this->backup_finish($next_resumption, true, true, $resumption_no);
|
386 |
+
|
387 |
+
}
|
388 |
+
|
389 |
+
function backup_all() {
|
390 |
+
$this->boot_backup(true,true);
|
391 |
+
}
|
392 |
+
|
393 |
+
function backup_files() {
|
394 |
+
# Note that the "false" for database gets over-ridden automatically if they turn out to have the same schedules
|
395 |
+
$this->boot_backup(true,false);
|
396 |
+
}
|
397 |
+
|
398 |
+
function backup_database() {
|
399 |
+
# Note that nothing will happen if the file backup had the same schedule
|
400 |
+
$this->boot_backup(false,true);
|
401 |
+
}
|
402 |
+
|
403 |
+
function jobdata_set($key, $value) {
|
404 |
+
if (is_array($this->jobdata)) {
|
405 |
+
$this->jobdata[$key] = $value;
|
406 |
+
} else {
|
407 |
+
$this->jobdata = array($key => $value);
|
408 |
+
}
|
409 |
+
set_transient("updraft_jobdata_".$this->nonce, $this->jobdata, 14400);
|
410 |
+
}
|
411 |
+
|
412 |
+
function jobdata_get($key) {
|
413 |
+
if (!is_array($this->jobdata)) {
|
414 |
+
$this->jobdata = get_transient("updraft_jobdata_".$this->nonce);
|
415 |
+
if (!is_array($this->jobdata)) return false;
|
416 |
+
}
|
417 |
+
return (isset($this->jobdata[$key])) ? $this->jobdata[$key] : false;
|
418 |
+
}
|
419 |
+
|
420 |
+
// This uses a transient; its only purpose is to indicate *total* completion; there is no actual danger, just wasted time, in resuming when it was not needed. So the transient just helps save resources.
|
421 |
+
function resumable_backup_of_files($resumption_no) {
|
422 |
+
//backup directories and return a numerically indexed array of file paths to the backup files
|
423 |
+
$transient_status = $this->jobdata_get('backup_files');
|
424 |
+
if ($transient_status == 'finished') {
|
425 |
+
$this->log("Creation of backups of directories: already finished");
|
426 |
+
} elseif ($transient_status == "begun") {
|
427 |
+
if ($resumption_no>0) {
|
428 |
+
$this->log("Creation of backups of directories: had begun; will resume");
|
429 |
+
} else {
|
430 |
+
$this->log("Creation of backups of directories: beginning");
|
431 |
+
}
|
432 |
+
} else {
|
433 |
+
# This is not necessarily a backup run which is meant to contain files at all
|
434 |
+
$this->log("This backup run is not intended for files - skipping");
|
435 |
+
return array();
|
436 |
+
}
|
437 |
+
// We want this array, even if already finished
|
438 |
+
$backup_array = $this->backup_dirs($transient_status);
|
439 |
+
// This can get over-written later
|
440 |
+
$this->jobdata_set('backup_files', 'finished');
|
441 |
+
return $backup_array;
|
442 |
+
}
|
443 |
+
|
444 |
+
// This procedure initiates a backup run
|
445 |
+
function boot_backup($backup_files, $backup_database) {
|
446 |
+
|
447 |
+
@ignore_user_abort(true);
|
448 |
+
|
449 |
+
//generate backup information
|
450 |
+
$this->backup_time_nonce();
|
451 |
+
$this->logfile_open($this->nonce);
|
452 |
+
|
453 |
+
// Some house-cleaning
|
454 |
+
$this->clean_temporary_files();
|
455 |
+
|
456 |
+
// Log some information that may be helpful
|
457 |
+
$this->log("Tasks: Backup files: $backup_files (schedule: ".UpdraftPlus_Options::get_updraft_option('updraft_interval', 'unset').") Backup DB: $backup_database (schedule: ".UpdraftPlus_Options::get_updraft_option('updraft_interval_database', 'unset').")");
|
458 |
+
|
459 |
+
# If the files and database schedules are the same, and if this the file one, then we rope in database too.
|
460 |
+
# On the other hand, if the schedules were the same and this was the database run, then there is nothing to do.
|
461 |
+
if (UpdraftPlus_Options::get_updraft_option('updraft_interval') == UpdraftPlus_Options::get_updraft_option('updraft_interval_database') || UpdraftPlus_Options::get_updraft_option('updraft_interval_database','xyz') == 'xyz' ) {
|
462 |
+
$backup_database = ($backup_files == true) ? true : false;
|
463 |
+
}
|
464 |
+
|
465 |
+
$this->log("Processed schedules. Tasks now: Backup files: $backup_files Backup DB: $backup_database");
|
466 |
+
|
467 |
+
# If nothing to be done, then just finish
|
468 |
+
if (!$backup_files && !$backup_database) {
|
469 |
+
$this->backup_finish(1, false, false, 0);
|
470 |
+
return;
|
471 |
+
}
|
472 |
+
|
473 |
+
// Save what *should* be done, to make it resumable from this point on
|
474 |
+
if ($backup_database) $this->jobdata_set("backup_database", 'begun');
|
475 |
+
if ($backup_files) $this->jobdata_set('backup_files', 'begun');
|
476 |
+
$this->jobdata_set('service', UpdraftPlus_Options::get_updraft_option('updraft_service'));
|
477 |
+
|
478 |
+
// This can be adapted if we see a need
|
479 |
+
$this->jobdata_set('resume_interval', 300);
|
480 |
+
|
481 |
+
$this->jobdata_set('backup_time', $this->backup_time);
|
482 |
+
|
483 |
+
// Everthing is now set up; now go
|
484 |
+
$this->backup_resume(0, $this->nonce);
|
485 |
+
|
486 |
+
}
|
487 |
+
|
488 |
+
// Encrypts the file if the option is set; returns the basename of the file (according to whether it was encrypted or nto)
|
489 |
+
function encrypt_file($file) {
|
490 |
+
$encryption = UpdraftPlus_Options::get_updraft_option('updraft_encryptionphrase');
|
491 |
+
if (strlen($encryption) > 0) {
|
492 |
+
$this->log("$file: applying encryption");
|
493 |
+
$encryption_error = 0;
|
494 |
+
$microstart = microtime(true);
|
495 |
+
require_once(UPDRAFTPLUS_DIR.'/includes/Rijndael.php');
|
496 |
+
$rijndael = new Crypt_Rijndael();
|
497 |
+
$rijndael->setKey($encryption);
|
498 |
+
$updraft_dir = $this->backups_dir_location();
|
499 |
+
$file_size = @filesize($updraft_dir.'/'.$file)/1024;
|
500 |
+
if (false === file_put_contents($updraft_dir.'/'.$file.'.crypt' , $rijndael->encrypt(file_get_contents($updraft_dir.'/'.$file)))) {$encryption_error = 1;}
|
501 |
+
if (0 == $encryption_error) {
|
502 |
+
$time_taken = max(0.000001, microtime(true)-$microstart);
|
503 |
+
$this->log("$file: encryption successful: ".round($file_size,1)."Kb in ".round($time_taken,1)."s (".round($file_size/$time_taken, 1)."Kb/s)");
|
504 |
+
# Delete unencrypted file
|
505 |
+
@unlink($updraft_dir.'/'.$file);
|
506 |
+
return basename($file.'.crypt');
|
507 |
+
} else {
|
508 |
+
$this->log("Encryption error occurred when encrypting database. Encryption aborted.");
|
509 |
+
$this->error("Encryption error occurred when encrypting database. Encryption aborted.");
|
510 |
+
return basename($file);
|
511 |
+
}
|
512 |
+
} else {
|
513 |
+
return basename($file);
|
514 |
+
}
|
515 |
+
}
|
516 |
+
|
517 |
+
function backup_finish($cancel_event, $clear_nonce_transient, $allow_email, $resumption_no) {
|
518 |
+
|
519 |
+
// In fact, leaving the hook to run (if debug is set) is harmless, as the resume job should only do tasks that were left unfinished, which at this stage is none.
|
520 |
+
if (empty($this->errors)) {
|
521 |
+
if ($clear_nonce_transient) {
|
522 |
+
$this->log("There were no errors in the uploads, so the 'resume' event is being unscheduled");
|
523 |
+
wp_clear_scheduled_hook('updraft_backup_resume', array($cancel_event, $this->nonce));
|
524 |
+
// TODO: Delete the job transient (is presently useful for debugging, and only lasts 4 hours)
|
525 |
+
}
|
526 |
+
} else {
|
527 |
+
$this->log("There were errors in the uploads, so the 'resume' event is remaining scheduled");
|
528 |
+
}
|
529 |
+
|
530 |
+
// Send the results email if appropriate, which means:
|
531 |
+
// - The caller allowed it (which is not the case in an 'empty' run)
|
532 |
+
// - And: An email address was set (which must be so in email mode)
|
533 |
+
// And one of:
|
534 |
+
// - Debug mode
|
535 |
+
// - There were no errors (which means we completed and so this is the final run - time for the final report)
|
536 |
+
// - It was the tenth resumption; everything failed
|
537 |
+
|
538 |
+
$send_an_email = false;
|
539 |
+
|
540 |
+
// Make sure that the final status is shown
|
541 |
+
if (empty($this->errors)) {
|
542 |
+
$send_an_email = true;
|
543 |
+
$final_message = "The backup apparently succeeded and is now complete";
|
544 |
+
} elseif ($this->newresumption_scheduled == false) {
|
545 |
+
$send_an_email = true;
|
546 |
+
$final_message = "The backup attempt has finished, apparently unsuccessfully";
|
547 |
+
} else {
|
548 |
+
// There are errors, but a resumption will be attempted
|
549 |
+
$final_message = "The backup has not finished; a resumption is scheduled within 5 minutes";
|
550 |
+
}
|
551 |
+
|
552 |
+
// Now over-ride the decision to send an email, if needed
|
553 |
+
if (UpdraftPlus_Options::get_updraft_option('updraft_debug_mode')) {
|
554 |
+
$send_an_email = true;
|
555 |
+
$this->log("An email has been scheduled for this job, because we are in debug mode");
|
556 |
+
}
|
557 |
+
// If there's no email address, or the set was empty, that is the final over-ride: don't send
|
558 |
+
if (!$allow_email) {
|
559 |
+
$send_an_email = false;
|
560 |
+
$this->log("No email will be sent - this backup set was empty.");
|
561 |
+
} elseif (UpdraftPlus_Options::get_updraft_option('updraft_email') == '') {
|
562 |
+
$send_an_email = false;
|
563 |
+
$this->log("No email will/can be sent - the user has not configured an email address.");
|
564 |
+
}
|
565 |
+
|
566 |
+
if ($send_an_email) $this->send_results_email($final_message);
|
567 |
+
|
568 |
+
$this->log($final_message);
|
569 |
+
|
570 |
+
@fclose($this->logfile_handle);
|
571 |
+
|
572 |
+
// Don't delete the log file now; delete it upon rotation
|
573 |
+
//if (!UpdraftPlus_Options::get_updraft_option('updraft_debug_mode')) @unlink($this->logfile_name);
|
574 |
+
|
575 |
+
}
|
576 |
+
|
577 |
+
function send_results_email($final_message) {
|
578 |
+
|
579 |
+
$debug_mode = UpdraftPlus_Options::get_updraft_option('updraft_debug_mode');
|
580 |
+
|
581 |
+
$sendmail_to = UpdraftPlus_Options::get_updraft_option('updraft_email');
|
582 |
+
|
583 |
+
$backup_files = $this->jobdata_get('backup_files');
|
584 |
+
$backup_db = $this->jobdata_get("backup_database");
|
585 |
+
|
586 |
+
if ($backup_files == 'finished' && ( $backup_db == 'finished' || $backup_db == 'encrypted' ) ) {
|
587 |
+
$backup_contains = "Files and database";
|
588 |
+
} elseif ($backup_files == 'finished') {
|
589 |
+
$backup_contains = ($backup_db == "begun") ? "Files (database backup has not completed)" : "Files only (database was not part of this particular schedule)";
|
590 |
+
} elseif ($backup_db == 'finished' || $backup_db == 'encrypted') {
|
591 |
+
$backup_contains = ($backup_files == "begun") ? "Database (files backup has not completed)" : "Database only (files were not part of this particular schedule)";
|
592 |
+
} else {
|
593 |
+
$backup_contains = "Unknown/unexpected error - please raise a support request";
|
594 |
+
}
|
595 |
+
|
596 |
+
$this->log("Sending email ('$backup_contains') report to: ".substr($sendmail_to, 0, 5)."...");
|
597 |
+
|
598 |
+
$append_log = ($debug_mode && $this->logfile_name != "") ? "\r\nLog contents:\r\n".file_get_contents($this->logfile_name) : "" ;
|
599 |
+
|
600 |
+
wp_mail($sendmail_to,'Backed up: '.get_bloginfo('name').' (UpdraftPlus '.$this->version.') '.date('Y-m-d H:i',time()),'Site: '.site_url()."\r\nUpdraftPlus WordPress backup is complete.\r\nBackup contains: ".$backup_contains."\r\nLatest status: $final_message\r\n\r\n".$this->wordshell_random_advert(0)."\r\n".$append_log);
|
601 |
+
|
602 |
+
}
|
603 |
+
|
604 |
+
function save_last_backup($backup_array) {
|
605 |
+
$success = (empty($this->errors)) ? 1 : 0;
|
606 |
+
|
607 |
+
$last_backup = array('backup_time'=>$this->backup_time, 'backup_array'=>$backup_array, 'success'=>$success, 'errors'=>$this->errors, 'backup_nonce' => $this->nonce);
|
608 |
+
|
609 |
+
UpdraftPlus_Options::update_updraft_option('updraft_last_backup', $last_backup);
|
610 |
+
}
|
611 |
+
|
612 |
+
// This should be called whenever a file is successfully uploaded
|
613 |
+
function uploaded_file($file, $id = false) {
|
614 |
+
$hash = md5($file);
|
615 |
+
$this->log("Recording as successfully uploaded: $file ($hash)");
|
616 |
+
$this->jobdata_set("uploaded_$hash", "yes");
|
617 |
+
if ($id) {
|
618 |
+
$ids = UpdraftPlus_Options::get_updraft_option('updraft_file_ids', array() );
|
619 |
+
$ids[$file] = $id;
|
620 |
+
UpdraftPlus_Options::update_updraft_option('updraft_file_ids',$ids);
|
621 |
+
$this->log("Stored file<->id correlation in database ($file <-> $id)");
|
622 |
+
}
|
623 |
+
// Delete local files immediately if the option is set
|
624 |
+
// Where we are only backing up locally, only the "prune" function should do deleting
|
625 |
+
if ($this->jobdata_get('service') != '' && $this->jobdata_get('service') != 'none') $this->delete_local($file);
|
626 |
+
}
|
627 |
+
|
628 |
+
// Dispatch to the relevant function
|
629 |
+
function cloud_backup($backup_array) {
|
630 |
+
|
631 |
+
$service = $this->jobdata_get('service');
|
632 |
+
$this->log("Cloud backup selection: ".$service);
|
633 |
+
@set_time_limit(900);
|
634 |
+
|
635 |
+
$method_include = UPDRAFTPLUS_DIR.'/methods/'.$service.'.php';
|
636 |
+
if (file_exists($method_include)) require_once($method_include);
|
637 |
+
|
638 |
+
if ($service == "none") {
|
639 |
+
$this->log("No remote despatch: user chose no remote backup service");
|
640 |
+
} else {
|
641 |
+
$this->log("Beginning dispatch of backup to remote");
|
642 |
+
}
|
643 |
+
|
644 |
+
$objname = "UpdraftPlus_BackupModule_${service}";
|
645 |
+
if (method_exists($objname, "backup")) {
|
646 |
+
// New style - external, allowing more plugability
|
647 |
+
$remote_obj = new $objname;
|
648 |
+
$remote_obj->backup($backup_array);
|
649 |
+
} elseif ($service == "none") {
|
650 |
+
$this->prune_retained_backups("none", null, null);
|
651 |
+
}
|
652 |
+
}
|
653 |
+
|
654 |
+
function prune_file($service, $dofile, $method_object = null, $object_passback = null ) {
|
655 |
+
$this->log("Delete this file: $dofile, service=$service");
|
656 |
+
$fullpath = $this->backups_dir_location().'/'.$dofile;
|
657 |
+
// delete it if it's locally available
|
658 |
+
if (file_exists($fullpath)) {
|
659 |
+
$this->log("Deleting local copy ($fullpath)");
|
660 |
+
@unlink($fullpath);
|
661 |
+
}
|
662 |
+
|
663 |
+
// Despatch to the particular method's deletion routine
|
664 |
+
if (!is_null($method_object)) $method_object->delete($dofile, $object_passback);
|
665 |
+
}
|
666 |
+
|
667 |
+
// Carries out retain behaviour. Pass in a valid S3 or FTP object and path if relevant.
|
668 |
+
function prune_retained_backups($service, $backup_method_object = null, $backup_passback = null) {
|
669 |
+
|
670 |
+
// If they turned off deletion on local backups, then there is nothing to do
|
671 |
+
if (UpdraftPlus_Options::get_updraft_option('updraft_delete_local') == 0 && $service == 'none') {
|
672 |
+
$this->log("Prune old backups from local store: nothing to do, since the user disabled local deletion and we are using local backups");
|
673 |
+
return;
|
674 |
+
}
|
675 |
+
|
676 |
+
$this->log("Retain: beginning examination of existing backup sets");
|
677 |
+
|
678 |
+
// Number of backups to retain - files
|
679 |
+
$updraft_retain = UpdraftPlus_Options::get_updraft_option('updraft_retain', 1);
|
680 |
+
$updraft_retain = (is_numeric($updraft_retain)) ? $updraft_retain : 1;
|
681 |
+
$this->log("Retain files: user setting: number to retain = $updraft_retain");
|
682 |
+
|
683 |
+
// Number of backups to retain - db
|
684 |
+
$updraft_retain_db = UpdraftPlus_Options::get_updraft_option('updraft_retain_db', $updraft_retain);
|
685 |
+
$updraft_retain_db = (is_numeric($updraft_retain_db)) ? $updraft_retain_db : 1;
|
686 |
+
$this->log("Retain db: user setting: number to retain = $updraft_retain_db");
|
687 |
+
|
688 |
+
// Returns an array, most recent first, of backup sets
|
689 |
+
$backup_history = $this->get_backup_history();
|
690 |
+
$db_backups_found = 0;
|
691 |
+
$file_backups_found = 0;
|
692 |
+
$this->log("Number of backup sets in history: ".count($backup_history));
|
693 |
+
|
694 |
+
foreach ($backup_history as $backup_datestamp => $backup_to_examine) {
|
695 |
+
// $backup_to_examine is an array of file names, keyed on db/plugins/themes/uploads
|
696 |
+
// The new backup_history array is saved afterwards, so remember to unset the ones that are to be deleted
|
697 |
+
$this->log("Examining backup set with datestamp: $backup_datestamp");
|
698 |
+
|
699 |
+
if (isset($backup_to_examine['db'])) {
|
700 |
+
$db_backups_found++;
|
701 |
+
$this->log("$backup_datestamp: this set includes a database (".$backup_to_examine['db']."); db count is now $db_backups_found");
|
702 |
+
if ($db_backups_found > $updraft_retain_db) {
|
703 |
+
$this->log("$backup_datestamp: over retain limit ($updraft_retain_db); will delete this database");
|
704 |
+
$dofile = $backup_to_examine['db'];
|
705 |
+
if (!empty($dofile)) $this->prune_file($service, $dofile, $backup_method_object, $backup_passback);
|
706 |
+
unset($backup_to_examine['db']);
|
707 |
+
}
|
708 |
+
}
|
709 |
+
if (isset($backup_to_examine['plugins']) || isset($backup_to_examine['themes']) || isset($backup_to_examine['uploads']) || isset($backup_to_examine['others'])) {
|
710 |
+
$file_backups_found++;
|
711 |
+
$this->log("$backup_datestamp: this set includes files; fileset count is now $file_backups_found");
|
712 |
+
if ($file_backups_found > $updraft_retain) {
|
713 |
+
$this->log("$backup_datestamp: over retain limit ($updraft_retain); will delete this file set");
|
714 |
+
$file = isset($backup_to_examine['plugins']) ? $backup_to_examine['plugins'] : "";
|
715 |
+
$file2 = isset($backup_to_examine['themes']) ? $backup_to_examine['themes'] : "";
|
716 |
+
$file3 = isset($backup_to_examine['uploads']) ? $backup_to_examine['uploads'] : "";
|
717 |
+
$file4 = isset($backup_to_examine['others']) ? $backup_to_examine['others'] : "";
|
718 |
+
foreach (array($file, $file2, $file3, $file4) as $dofile) {
|
719 |
+
if (!empty($dofile)) $this->prune_file($service, $dofile, $backup_method_object, $backup_passback);
|
720 |
+
}
|
721 |
+
unset($backup_to_examine['plugins']);
|
722 |
+
unset($backup_to_examine['themes']);
|
723 |
+
unset($backup_to_examine['uploads']);
|
724 |
+
unset($backup_to_examine['others']);
|
725 |
+
}
|
726 |
+
}
|
727 |
+
// Delete backup set completely if empty, o/w just remove DB
|
728 |
+
if (count($backup_to_examine) == 0 || (count($backup_to_examine) == 1 && isset($backup_to_examine['nonce']))) {
|
729 |
+
$this->log("$backup_datestamp: this backup set is now empty; will remove from history");
|
730 |
+
unset($backup_history[$backup_datestamp]);
|
731 |
+
if (isset($backup_to_examine['nonce'])) {
|
732 |
+
$fullpath = $this->backups_dir_location().'/log.'.$backup_to_examine['nonce'].'.txt';
|
733 |
+
if (is_file($fullpath)) {
|
734 |
+
$this->log("$backup_datestamp: deleting log file (log.".$backup_to_examine['nonce'].".txt)");
|
735 |
+
@unlink($fullpath);
|
736 |
+
} else {
|
737 |
+
$this->log("$backup_datestamp: corresponding log file not found - must have already been deleted");
|
738 |
+
}
|
739 |
+
} else {
|
740 |
+
$this->log("$backup_datestamp: no nonce record found in the backup set, so cannot delete any remaining log file");
|
741 |
+
}
|
742 |
+
} else {
|
743 |
+
$this->log("$backup_datestamp: this backup set remains non-empty; will retain in history");
|
744 |
+
$backup_history[$backup_datestamp] = $backup_to_examine;
|
745 |
+
}
|
746 |
+
}
|
747 |
+
$this->log("Retain: saving new backup history (sets now: ".count($backup_history).") and finishing retain operation");
|
748 |
+
UpdraftPlus_Options::update_updraft_option('updraft_backup_history',$backup_history);
|
749 |
+
}
|
750 |
+
|
751 |
+
function delete_local($file) {
|
752 |
+
if(UpdraftPlus_Options::get_updraft_option('updraft_delete_local')) {
|
753 |
+
$this->log("Deleting local file: $file");
|
754 |
+
//need error checking so we don't delete what isn't successfully uploaded?
|
755 |
+
$fullpath = $this->backups_dir_location().'/'.$file;
|
756 |
+
return unlink($fullpath);
|
757 |
+
}
|
758 |
+
return true;
|
759 |
+
}
|
760 |
+
|
761 |
+
function reschedule($how_far_ahead) {
|
762 |
+
// Reschedule - remove presently scheduled event
|
763 |
+
wp_clear_scheduled_hook('updraft_backup_resume', array($this->current_resumption + 1, $this->nonce));
|
764 |
+
// Add new event
|
765 |
+
if ($how_far_ahead < 200) $how_far_ahead=200;
|
766 |
+
$schedule_for = time() + $how_far_ahead;
|
767 |
+
wp_schedule_single_event($schedule_for, 'updraft_backup_resume', array($this->current_resumption + 1, $this->nonce));
|
768 |
+
$this->newresumption_scheduled = $schedule_for;
|
769 |
+
}
|
770 |
+
|
771 |
+
function increase_resume_and_reschedule($howmuch = 120) {
|
772 |
+
$resume_interval = $this->jobdata_get('resume_interval');
|
773 |
+
if (!is_numeric($resume_interval) || $resume_interval<200) { $resume_interval = 200; }
|
774 |
+
if ($this->newresumption_scheduled != false) $this->reschedule($resume_interval+$howmuch);
|
775 |
+
$this->jobdata_set('resume_interval', $resume_interval+$howmuch);
|
776 |
+
$this->log("To decrease the likelihood of overlaps, increasing resumption interval to: ".($resume_interval+$howmuch));
|
777 |
+
}
|
778 |
+
|
779 |
+
function create_zip($create_from_dir, $whichone, $create_in_dir, $backup_file_basename) {
|
780 |
+
// Note: $create_from_dir can be an array or a string
|
781 |
+
@set_time_limit(900);
|
782 |
+
|
783 |
+
if ($whichone != "others") $this->log("Beginning creation of dump of $whichone");
|
784 |
+
|
785 |
+
$full_path = $create_in_dir.'/'.$backup_file_basename.'-'.$whichone.'.zip';
|
786 |
+
|
787 |
+
if (file_exists($full_path)) {
|
788 |
+
$this->log("$backup_file_basename-$whichone.zip: this file has already been created");
|
789 |
+
return basename($full_path);
|
790 |
+
}
|
791 |
+
|
792 |
+
// Temporary file, to be able to detect actual completion (upon which, it is renamed)
|
793 |
+
|
794 |
+
// Firstly, make sure that the temporary file is not already being written to - which can happen if a resumption takes place whilst an old run is still active
|
795 |
+
$zip_name = $full_path.'.tmp';
|
796 |
+
$time_now = time();
|
797 |
+
$time_mod = (int)@filemtime($zip_name);
|
798 |
+
if (file_exists($zip_name) && $time_mod>100 && ($time_now-$time_mod)<30) {
|
799 |
+
$file_size = filesize($zip_name);
|
800 |
+
$this->log("Terminate: the temporary file $zip_name already exists, and was modified within the last 30 seconds (time_mod=$time_mod, time_now=$time_now, diff=".($time_now-$time_mod).", size=$file_size). This likely means that another UpdraftPlus run is still at work; so we will exit.");
|
801 |
+
$this->increase_resume_and_reschedule(120);
|
802 |
+
die;
|
803 |
+
} elseif (file_exists($zip_name)) {
|
804 |
+
$this->log("File exists ($zip_name), but was apparently not modified within the last 30 seconds, so we assume that any previous run has now terminated (time_mod=$time_mod, time_now=$time_now, diff=".($time_now-$time_mod).")");
|
805 |
+
}
|
806 |
+
|
807 |
+
$microtime_start = microtime(true);
|
808 |
+
# The paths in the zip should then begin with '$whichone', having removed WP_CONTENT_DIR from the front
|
809 |
+
$zipcode = $this->make_zipfile($create_from_dir, $zip_name);
|
810 |
+
if ($zipcode !== true) {
|
811 |
+
$this->log("ERROR: Zip failure: /*Could not create*/ $whichone zip: code=$zipcode");
|
812 |
+
$this->error("Could not create $whichone zip: code $zipcode. Consult the log file for more information.");
|
813 |
+
return false;
|
814 |
+
} else {
|
815 |
+
rename($full_path.'.tmp', $full_path);
|
816 |
+
$timetaken = max(microtime(true)-$microtime_start, 0.000001);
|
817 |
+
$kbsize = filesize($full_path)/1024;
|
818 |
+
$rate = round($kbsize/$timetaken, 1);
|
819 |
+
$this->log("Created $whichone zip - file size is ".round($kbsize,1)." Kb in ".round($timetaken,1)." s ($rate Kb/s)");
|
820 |
+
}
|
821 |
+
|
822 |
+
return basename($full_path);
|
823 |
+
}
|
824 |
+
|
825 |
+
// This function is resumable
|
826 |
+
function backup_dirs($transient_status) {
|
827 |
+
|
828 |
+
if(!$this->backup_time) $this->backup_time_nonce();
|
829 |
+
|
830 |
+
$updraft_dir = $this->backups_dir_location();
|
831 |
+
if(!is_writable($updraft_dir)) {
|
832 |
+
$this->log("Backup directory ($updraft_dir) is not writable, or does not exist");
|
833 |
+
$this->error("Backup directory ($updraft_dir) is not writable, or does not exist.");
|
834 |
+
return array();
|
835 |
+
}
|
836 |
+
|
837 |
+
//get the blog name and rip out all non-alphanumeric chars other than _
|
838 |
+
$blog_name = str_replace(' ','_',substr(get_bloginfo(), 0, 96));
|
839 |
+
$blog_name = preg_replace('/[^A-Za-z0-9_]/','', $blog_name);
|
840 |
+
if(!$blog_name) $blog_name = 'non_alpha_name';
|
841 |
+
|
842 |
+
$backup_file_basename = 'backup_'.date('Y-m-d-Hi', $this->backup_time).'_'.$blog_name.'_'.$this->nonce;
|
843 |
+
|
844 |
+
$backup_array = array();
|
845 |
+
|
846 |
+
$wp_themes_dir = WP_CONTENT_DIR.'/themes';
|
847 |
+
$wp_upload_dir = wp_upload_dir();
|
848 |
+
$wp_upload_dir = $wp_upload_dir['basedir'];
|
849 |
+
$wp_plugins_dir = WP_PLUGIN_DIR;
|
850 |
+
|
851 |
+
$possible_backups = array ('plugins' => $wp_plugins_dir, 'themes' => $wp_themes_dir, 'uploads' => $wp_upload_dir);
|
852 |
+
|
853 |
+
# Plugins, themes, uploads
|
854 |
+
foreach ($possible_backups as $youwhat => $whichdir) {
|
855 |
+
if (UpdraftPlus_Options::get_updraft_option("updraft_include_$youwhat", true)) {
|
856 |
+
if ($transient_status == 'finished') {
|
857 |
+
$backup_array[$youwhat] = $backup_file_basename.'-'.$youwhat.'.zip';
|
858 |
+
} else {
|
859 |
+
$created = $this->create_zip($whichdir, $youwhat, $updraft_dir, $backup_file_basename);
|
860 |
+
if ($created) $backup_array[$youwhat] = $created;
|
861 |
+
}
|
862 |
+
} else {
|
863 |
+
$this->log("No backup of $youwhat: excluded by user's options");
|
864 |
+
}
|
865 |
+
}
|
866 |
+
|
867 |
+
# Others
|
868 |
+
if (UpdraftPlus_Options::get_updraft_option('updraft_include_others', true)) {
|
869 |
+
|
870 |
+
if ($transient_status == 'finished') {
|
871 |
+
$backup_array['others'] = $backup_file_basename.'-others.zip';
|
872 |
+
} else {
|
873 |
+
$this->log("Beginning backup of other directories found in the content directory");
|
874 |
+
|
875 |
+
// http://www.phpconcept.net/pclzip/user-guide/53
|
876 |
+
/* First parameter to create is:
|
877 |
+
An array of filenames or dirnames,
|
878 |
+
or
|
879 |
+
A string containing the filename or a dirname,
|
880 |
+
or
|
881 |
+
A string containing a list of filename or dirname separated by a comma.
|
882 |
+
*/
|
883 |
+
|
884 |
+
# Initialise
|
885 |
+
$other_dirlist = array();
|
886 |
+
|
887 |
+
$others_skip = preg_split("/,/",UpdraftPlus_Options::get_updraft_option('updraft_include_others_exclude', UPDRAFT_DEFAULT_OTHERS_EXCLUDE));
|
888 |
+
# Make the values into the keys
|
889 |
+
$others_skip = array_flip($others_skip);
|
890 |
+
|
891 |
+
$this->log('Looking for candidates to back up in: '.WP_CONTENT_DIR);
|
892 |
+
if ($handle = opendir(WP_CONTENT_DIR)) {
|
893 |
+
while (false !== ($entry = readdir($handle))) {
|
894 |
+
$candidate = WP_CONTENT_DIR.'/'.$entry;
|
895 |
+
if ($entry == "." || $entry == "..") { ; }
|
896 |
+
elseif ($candidate == $updraft_dir) { $this->log("others: $entry: skipping: this is the updraft directory"); }
|
897 |
+
elseif ($candidate == $wp_themes_dir) { $this->log("others: $entry: skipping: this is the themes directory"); }
|
898 |
+
elseif ($candidate == $wp_upload_dir) { $this->log("others: $entry: skipping: this is the uploads directory"); }
|
899 |
+
elseif ($candidate == $wp_plugins_dir) { $this->log("others: $entry: skipping: this is the plugins directory"); }
|
900 |
+
elseif (isset($others_skip[$entry])) { $this->log("others: $entry: skipping: excluded by options"); }
|
901 |
+
else { $this->log("others: $entry: adding to list"); array_push($other_dirlist, $candidate); }
|
902 |
+
}
|
903 |
+
@closedir($handle);
|
904 |
+
} else {
|
905 |
+
$this->log('ERROR: Could not read the content directory: '.WP_CONTENT_DIR);
|
906 |
+
$this->error('Could not read the content directory: '.WP_CONTENT_DIR);
|
907 |
+
}
|
908 |
+
|
909 |
+
if (count($other_dirlist)>0) {
|
910 |
+
$created = $this->create_zip($other_dirlist, 'others', $updraft_dir, $backup_file_basename);
|
911 |
+
if ($created) $backup_array['others'] = $created;
|
912 |
+
} else {
|
913 |
+
$this->log("No backup of other directories: there was nothing found to back up");
|
914 |
+
}
|
915 |
+
# If we are not already finished
|
916 |
+
}
|
917 |
+
} else {
|
918 |
+
$this->log("No backup of other directories: excluded by user's options");
|
919 |
+
}
|
920 |
+
return $backup_array;
|
921 |
+
}
|
922 |
+
|
923 |
+
function save_backup_history($backup_array) {
|
924 |
+
if(is_array($backup_array)) {
|
925 |
+
$backup_history = UpdraftPlus_Options::get_updraft_option('updraft_backup_history');
|
926 |
+
$backup_history = (is_array($backup_history)) ? $backup_history : array();
|
927 |
+
$backup_array['nonce'] = $this->nonce;
|
928 |
+
$backup_history[$this->backup_time] = $backup_array;
|
929 |
+
UpdraftPlus_Options::update_updraft_option('updraft_backup_history',$backup_history);
|
930 |
+
} else {
|
931 |
+
$this->log('Could not save backup history because we have no backup array. Backup probably failed.');
|
932 |
+
$this->error('Could not save backup history because we have no backup array. Backup probably failed.');
|
933 |
+
}
|
934 |
+
}
|
935 |
+
|
936 |
+
function get_backup_history() {
|
937 |
+
//$backup_history = UpdraftPlus_Options::get_updraft_option('updraft_backup_history');
|
938 |
+
//by doing a raw DB query to get the most up-to-date data from this option we slightly narrow the window for the multiple-cron race condition
|
939 |
+
global $wpdb;
|
940 |
+
$backup_history = @unserialize($wpdb->get_var($wpdb->prepare("SELECT option_value from $wpdb->options WHERE option_name='updraft_backup_history'")));
|
941 |
+
if(is_array($backup_history)) {
|
942 |
+
krsort($backup_history); //reverse sort so earliest backup is last on the array. Then we can array_pop.
|
943 |
+
} else {
|
944 |
+
$backup_history = array();
|
945 |
+
}
|
946 |
+
return $backup_history;
|
947 |
+
}
|
948 |
+
|
949 |
+
// Open a file, store its filehandle
|
950 |
+
function backup_db_open($file, $allow_gz = true) {
|
951 |
+
if (function_exists('gzopen') && $allow_gz == true) {
|
952 |
+
$this->dbhandle = @gzopen($file, 'w');
|
953 |
+
$this->dbhandle_isgz = true;
|
954 |
+
} else {
|
955 |
+
$this->dbhandle = @fopen($file, 'w');
|
956 |
+
$this->dbhandle_isgz = false;
|
957 |
+
}
|
958 |
+
if(!$this->dbhandle) {
|
959 |
+
$this->log("ERROR: $file: Could not open the backup file for writing");
|
960 |
+
$this->error("$file: Could not open the backup file for writing");
|
961 |
+
}
|
962 |
+
}
|
963 |
+
|
964 |
+
function backup_db_header() {
|
965 |
+
|
966 |
+
//Begin new backup of MySql
|
967 |
+
$this->stow("# " . 'WordPress MySQL database backup' . "\n");
|
968 |
+
$this->stow("#\n");
|
969 |
+
$this->stow("# " . sprintf(__('Generated: %s','wp-db-backup'),date("l j. F Y H:i T")) . "\n");
|
970 |
+
$this->stow("# " . sprintf(__('Hostname: %s','wp-db-backup'),DB_HOST) . "\n");
|
971 |
+
$this->stow("# " . sprintf(__('Database: %s','wp-db-backup'),$this->backquote(DB_NAME)) . "\n");
|
972 |
+
$this->stow("# --------------------------------------------------------\n");
|
973 |
+
|
974 |
+
if (defined("DB_CHARSET")) {
|
975 |
+
$this->stow("/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;\n");
|
976 |
+
$this->stow("/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;\n");
|
977 |
+
$this->stow("/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;\n");
|
978 |
+
$this->stow("/*!40101 SET NAMES " . DB_CHARSET . " */;\n");
|
979 |
+
}
|
980 |
+
$this->stow("/*!40101 SET foreign_key_checks = 0 */;\n");
|
981 |
+
}
|
982 |
+
|
983 |
+
/* This function is resumable, using the following method:
|
984 |
+
- Each table is written out to ($final_filename).table.tmp
|
985 |
+
- When the writing finishes, it is renamed to ($final_filename).table
|
986 |
+
- When all tables are finished, they are concatenated into the final file
|
987 |
+
*/
|
988 |
+
function backup_db($already_done = "begun") {
|
989 |
+
|
990 |
+
// Get the file prefix
|
991 |
+
$updraft_dir = $this->backups_dir_location();
|
992 |
+
|
993 |
+
if(!$this->backup_time) $this->backup_time_nonce();
|
994 |
+
if (!$this->opened_log_time) $this->logfile_open($this->nonce);
|
995 |
+
|
996 |
+
// Get the blog name and rip out all non-alphanumeric chars other than _
|
997 |
+
$blog_name = preg_replace('/[^A-Za-z0-9_]/','', str_replace(' ','_', substr(get_bloginfo(), 0, 96)));
|
998 |
+
if (!$blog_name) $blog_name = 'non_alpha_name';
|
999 |
+
$file_base = 'backup_'.date('Y-m-d-Hi',$this->backup_time).'_'.$blog_name.'_'.$this->nonce;
|
1000 |
+
$backup_file_base = $updraft_dir.'/'.$file_base;
|
1001 |
+
|
1002 |
+
if ('finished' == $already_done) return basename($backup_file_base.'-db.gz');
|
1003 |
+
if ('encrypted' == $already_done) return basename($backup_file_base.'-db.gz.crypt');
|
1004 |
+
|
1005 |
+
$total_tables = 0;
|
1006 |
+
|
1007 |
+
global $table_prefix, $wpdb;
|
1008 |
+
|
1009 |
+
$all_tables = $wpdb->get_results("SHOW TABLES", ARRAY_N);
|
1010 |
+
$all_tables = array_map(create_function('$a', 'return $a[0];'), $all_tables);
|
1011 |
+
|
1012 |
+
if (!is_writable($updraft_dir)) {
|
1013 |
+
$this->log("The backup directory ($updraft_dir) is not writable.");
|
1014 |
+
$this->error("The backup directory ($updraft_dir) is not writable.");
|
1015 |
+
return false;
|
1016 |
+
}
|
1017 |
+
|
1018 |
+
$stitch_files = array();
|
1019 |
+
|
1020 |
+
foreach ($all_tables as $table) {
|
1021 |
+
$total_tables++;
|
1022 |
+
// Increase script execution time-limit to 15 min for every table.
|
1023 |
+
if ( !@ini_get('safe_mode') || strtolower(@ini_get('safe_mode')) == "off") @set_time_limit(15*60);
|
1024 |
+
// The table file may already exist if we have produced it on a previous run
|
1025 |
+
$table_file_prefix = $file_base.'-db-table-'.$table.'.table';
|
1026 |
+
if (file_exists($updraft_dir.'/'.$table_file_prefix.'.gz')) {
|
1027 |
+
$this->log("Table $table: corresponding file already exists; moving on");
|
1028 |
+
} else {
|
1029 |
+
// Open file, store the handle
|
1030 |
+
$this->backup_db_open($updraft_dir.'/'.$table_file_prefix.'.tmp.gz', true);
|
1031 |
+
# === is needed, otherwise 'false' matches (i.e. prefix does not match)
|
1032 |
+
if ( strpos($table, $table_prefix) === 0 ) {
|
1033 |
+
// Create the SQL statements
|
1034 |
+
$this->stow("# --------------------------------------------------------\n");
|
1035 |
+
$this->stow("# " . sprintf(__('Table: %s','wp-db-backup'),$this->backquote($table)) . "\n");
|
1036 |
+
$this->stow("# --------------------------------------------------------\n");
|
1037 |
+
$this->backup_table($table);
|
1038 |
+
} else {
|
1039 |
+
$this->stow("# --------------------------------------------------------\n");
|
1040 |
+
$this->stow("# " . sprintf(__('Skipping non-WP table: %s','wp-db-backup'),$this->backquote($table)) . "\n");
|
1041 |
+
$this->stow("# --------------------------------------------------------\n");
|
1042 |
+
}
|
1043 |
+
// Close file
|
1044 |
+
$this->close($this->dbhandle);
|
1045 |
+
$this->log("Table $table: finishing file (${table_file_prefix}.gz)");
|
1046 |
+
rename($updraft_dir.'/'.$table_file_prefix.'.tmp.gz', $updraft_dir.'/'.$table_file_prefix.'.gz');
|
1047 |
+
}
|
1048 |
+
$stitch_files[] = $table_file_prefix;
|
1049 |
+
}
|
1050 |
+
|
1051 |
+
// Race detection - with zip files now being resumable, these can more easily occur, with two running side-by-side
|
1052 |
+
$backup_final_file_name = $backup_file_base.'-db.gz';
|
1053 |
+
$time_now = time();
|
1054 |
+
$time_mod = (int)@filemtime($backup_final_file_name);
|
1055 |
+
if (file_exists($backup_final_file_name) && $time_mod>100 && ($time_now-$time_mod)<20) {
|
1056 |
+
$file_size = filesize($backup_final_file_name);
|
1057 |
+
$this->log("Terminate: the final database file ($backup_final_file_name) exists, and was modified within the last 20 seconds (time_mod=$time_mod, time_now=$time_now, diff=".($time_now-$time_mod).", size=$file_size). This likely means that another UpdraftPlus run is at work; so we will exit.");
|
1058 |
+
$this->increase_resume_and_reschedule(120);
|
1059 |
+
die;
|
1060 |
+
} elseif (file_exists($backup_final_file_name)) {
|
1061 |
+
$this->log("The final database file ($backup_final_file_name) exists, but was apparently not modified within the last 20 seconds (time_mod=$time_mod, time_now=$time_now, diff=".($time_now-$time_mod)."). Thus we assume that another UpdraftPlus terminated; thus we will continue.");
|
1062 |
+
}
|
1063 |
+
|
1064 |
+
// Finally, stitch the files together
|
1065 |
+
$this->backup_db_open($backup_final_file_name, true);
|
1066 |
+
$this->backup_db_header();
|
1067 |
+
|
1068 |
+
// We delay the unlinking because if two runs go concurrently and fail to detect each other (should not happen, but there's no harm in assuming the detection failed) then that leads to files missing from the db dump
|
1069 |
+
$unlink_files = array();
|
1070 |
+
|
1071 |
+
foreach ($stitch_files as $table_file) {
|
1072 |
+
$this->log("{$table_file}.gz: adding to final database dump");
|
1073 |
+
if (!$handle = gzopen($updraft_dir.'/'.$table_file.'.gz', "r")) {
|
1074 |
+
$this->log("Error: Failed to open database file for reading: ${table_file}.gz");
|
1075 |
+
$this->error(" Failed to open database file for reading: ${table_file}.gz");
|
1076 |
+
} else {
|
1077 |
+
while ($line = gzgets($handle, 2048)) { $this->stow($line); }
|
1078 |
+
gzclose($handle);
|
1079 |
+
$unlink_files[] = $updraft_dir.'/'.$table_file.'.gz';
|
1080 |
+
}
|
1081 |
+
}
|
1082 |
+
|
1083 |
+
if (defined("DB_CHARSET")) {
|
1084 |
+
$this->stow("/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\n");
|
1085 |
+
$this->stow("/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\n");
|
1086 |
+
$this->stow("/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n");
|
1087 |
+
}
|
1088 |
+
|
1089 |
+
$this->log($file_base.'-db.gz: finished writing out complete database file ('.round(filesize($backup_final_file_name)/1024,1).' Kb)');
|
1090 |
+
$this->close($this->dbhandle);
|
1091 |
+
|
1092 |
+
foreach ($unlink_files as $unlink_file) {
|
1093 |
+
@unlink($unlink_file);
|
1094 |
+
}
|
1095 |
+
|
1096 |
+
if (count($this->errors)) {
|
1097 |
+
return false;
|
1098 |
+
} else {
|
1099 |
+
# We no longer encrypt here - because the operation can take long, we made it resumable and moved it to the upload loop
|
1100 |
+
$this->log("Total database tables backed up: $total_tables");
|
1101 |
+
return basename($backup_file_base.'-db.gz');
|
1102 |
+
}
|
1103 |
+
|
1104 |
+
} //wp_db_backup
|
1105 |
+
|
1106 |
+
/**
|
1107 |
+
* Taken partially from phpMyAdmin and partially from
|
1108 |
+
* Alain Wolf, Zurich - Switzerland
|
1109 |
+
* Website: http://restkultur.ch/personal/wolf/scripts/db_backup/
|
1110 |
+
* Modified by Scott Merrill (http://www.skippy.net/)
|
1111 |
+
* to use the WordPress $wpdb object
|
1112 |
+
* @param string $table
|
1113 |
+
* @param string $segment
|
1114 |
+
* @return void
|
1115 |
+
*/
|
1116 |
+
function backup_table($table, $segment = 'none') {
|
1117 |
+
global $wpdb;
|
1118 |
+
|
1119 |
+
$microtime = microtime(true);
|
1120 |
+
|
1121 |
+
$total_rows = 0;
|
1122 |
+
|
1123 |
+
$table_structure = $wpdb->get_results("DESCRIBE $table");
|
1124 |
+
if (! $table_structure) {
|
1125 |
+
//$this->error(__('Error getting table details','wp-db-backup') . ": $table");
|
1126 |
+
return false;
|
1127 |
+
}
|
1128 |
+
|
1129 |
+
if(($segment == 'none') || ($segment == 0)) {
|
1130 |
+
// Add SQL statement to drop existing table
|
1131 |
+
$this->stow("\n\n");
|
1132 |
+
$this->stow("#\n");
|
1133 |
+
$this->stow("# " . sprintf(__('Delete any existing table %s','wp-db-backup'),$this->backquote($table)) . "\n");
|
1134 |
+
$this->stow("#\n");
|
1135 |
+
$this->stow("\n");
|
1136 |
+
$this->stow("DROP TABLE IF EXISTS " . $this->backquote($table) . ";\n");
|
1137 |
+
|
1138 |
+
// Table structure
|
1139 |
+
// Comment in SQL-file
|
1140 |
+
$this->stow("\n\n");
|
1141 |
+
$this->stow("#\n");
|
1142 |
+
$this->stow("# " . sprintf(__('Table structure of table %s','wp-db-backup'),$this->backquote($table)) . "\n");
|
1143 |
+
$this->stow("#\n");
|
1144 |
+
$this->stow("\n");
|
1145 |
+
|
1146 |
+
$create_table = $wpdb->get_results("SHOW CREATE TABLE $table", ARRAY_N);
|
1147 |
+
if (false === $create_table) {
|
1148 |
+
$err_msg = sprintf(__('Error with SHOW CREATE TABLE for %s.','wp-db-backup'), $table);
|
1149 |
+
//$this->error($err_msg);
|
1150 |
+
$this->stow("#\n# $err_msg\n#\n");
|
1151 |
+
}
|
1152 |
+
$this->stow($create_table[0][1] . ' ;');
|
1153 |
+
|
1154 |
+
if (false === $table_structure) {
|
1155 |
+
$err_msg = sprintf(__('Error getting table structure of %s','wp-db-backup'), $table);
|
1156 |
+
//$this->error($err_msg);
|
1157 |
+
$this->stow("#\n# $err_msg\n#\n");
|
1158 |
+
}
|
1159 |
+
|
1160 |
+
// Comment in SQL-file
|
1161 |
+
$this->stow("\n\n#\n# " . sprintf(__('Data contents of table %s','wp-db-backup'),$this->backquote($table)) . "\n#\n");
|
1162 |
+
}
|
1163 |
+
|
1164 |
+
// In UpdraftPlus, segment is always 'none'
|
1165 |
+
if(($segment == 'none') || ($segment >= 0)) {
|
1166 |
+
$defs = array();
|
1167 |
+
$integer_fields = array();
|
1168 |
+
// $table_structure was from "DESCRIBE $table"
|
1169 |
+
foreach ($table_structure as $struct) {
|
1170 |
+
if ( (0 === strpos($struct->Type, 'tinyint')) || (0 === strpos(strtolower($struct->Type), 'smallint')) ||
|
1171 |
+
(0 === strpos(strtolower($struct->Type), 'mediumint')) || (0 === strpos(strtolower($struct->Type), 'int')) || (0 === strpos(strtolower($struct->Type), 'bigint')) ) {
|
1172 |
+
$defs[strtolower($struct->Field)] = ( null === $struct->Default ) ? 'NULL' : $struct->Default;
|
1173 |
+
$integer_fields[strtolower($struct->Field)] = "1";
|
1174 |
+
}
|
1175 |
+
}
|
1176 |
+
|
1177 |
+
if($segment == 'none') {
|
1178 |
+
$row_start = 0;
|
1179 |
+
$row_inc = 100;
|
1180 |
+
} else {
|
1181 |
+
$row_start = $segment * 100;
|
1182 |
+
$row_inc = 100;
|
1183 |
+
}
|
1184 |
+
|
1185 |
+
do {
|
1186 |
+
if ( !@ini_get('safe_mode') || strtolower(@ini_get('safe_mode')) == "off") @set_time_limit(15*60);
|
1187 |
+
$table_data = $wpdb->get_results("SELECT * FROM $table LIMIT {$row_start}, {$row_inc}", ARRAY_A);
|
1188 |
+
$entries = 'INSERT INTO ' . $this->backquote($table) . ' VALUES (';
|
1189 |
+
// \x08\\x09, not required
|
1190 |
+
$search = array("\x00", "\x0a", "\x0d", "\x1a");
|
1191 |
+
$replace = array('\0', '\n', '\r', '\Z');
|
1192 |
+
if($table_data) {
|
1193 |
+
foreach ($table_data as $row) {
|
1194 |
+
$total_rows++;
|
1195 |
+
$values = array();
|
1196 |
+
foreach ($row as $key => $value) {
|
1197 |
+
if (isset($integer_fields[strtolower($key)])) {
|
1198 |
+
// make sure there are no blank spots in the insert syntax,
|
1199 |
+
// yet try to avoid quotation marks around integers
|
1200 |
+
$value = ( null === $value || '' === $value) ? $defs[strtolower($key)] : $value;
|
1201 |
+
$values[] = ( '' === $value ) ? "''" : $value;
|
1202 |
+
} else {
|
1203 |
+
$values[] = "'" . str_replace($search, $replace, str_replace('\'', '\\\'', str_replace('\\', '\\\\', $value))) . "'";
|
1204 |
+
}
|
1205 |
+
}
|
1206 |
+
$this->stow(" \n" . $entries . implode(', ', $values) . ');');
|
1207 |
+
}
|
1208 |
+
$row_start += $row_inc;
|
1209 |
+
}
|
1210 |
+
} while((count($table_data) > 0) and ($segment=='none'));
|
1211 |
+
}
|
1212 |
+
|
1213 |
+
if(($segment == 'none') || ($segment < 0)) {
|
1214 |
+
// Create footer/closing comment in SQL-file
|
1215 |
+
$this->stow("\n");
|
1216 |
+
$this->stow("#\n");
|
1217 |
+
$this->stow("# " . sprintf(__('End of data contents of table %s','wp-db-backup'),$this->backquote($table)) . "\n");
|
1218 |
+
$this->stow("# --------------------------------------------------------\n");
|
1219 |
+
$this->stow("\n");
|
1220 |
+
}
|
1221 |
+
$this->log("Table $table: Total rows added: $total_rows in ".sprintf("%.02f",max(microtime(true)-$microtime,0.00001))." seconds");
|
1222 |
+
|
1223 |
+
} // end backup_table()
|
1224 |
+
|
1225 |
+
function stow($query_line) {
|
1226 |
+
if ($this->dbhandle_isgz) {
|
1227 |
+
if(! @gzwrite($this->dbhandle, $query_line)) {
|
1228 |
+
//$this->error(__('There was an error writing a line to the backup script:','wp-db-backup') . ' ' . $query_line . ' ' . $php_errormsg);
|
1229 |
+
}
|
1230 |
+
} else {
|
1231 |
+
if(false === @fwrite($this->dbhandle, $query_line)) {
|
1232 |
+
//$this->error(__('There was an error writing a line to the backup script:','wp-db-backup') . ' ' . $query_line . ' ' . $php_errormsg);
|
1233 |
+
}
|
1234 |
+
}
|
1235 |
+
}
|
1236 |
+
|
1237 |
+
function close($handle) {
|
1238 |
+
if ($this->dbhandle_isgz) {
|
1239 |
+
gzclose($handle);
|
1240 |
+
} else {
|
1241 |
+
fclose($handle);
|
1242 |
+
}
|
1243 |
+
}
|
1244 |
+
|
1245 |
+
function error($error) {
|
1246 |
+
if (count($this->errors) == 0) $this->log("An error condition has occurred for the first time on this run");
|
1247 |
+
$this->errors[] = $error;
|
1248 |
+
return true;
|
1249 |
+
}
|
1250 |
+
|
1251 |
+
/**
|
1252 |
+
* Add backquotes to tables and db-names in
|
1253 |
+
* SQL queries. Taken from phpMyAdmin.
|
1254 |
+
*/
|
1255 |
+
function backquote($a_name) {
|
1256 |
+
if (!empty($a_name) && $a_name != '*') {
|
1257 |
+
if (is_array($a_name)) {
|
1258 |
+
$result = array();
|
1259 |
+
reset($a_name);
|
1260 |
+
while(list($key, $val) = each($a_name))
|
1261 |
+
$result[$key] = '`' . $val . '`';
|
1262 |
+
return $result;
|
1263 |
+
} else {
|
1264 |
+
return '`' . $a_name . '`';
|
1265 |
+
}
|
1266 |
+
} else {
|
1267 |
+
return $a_name;
|
1268 |
+
}
|
1269 |
+
}
|
1270 |
+
|
1271 |
+
/*END OF WP-DB-BACKUP BLOCK */
|
1272 |
+
|
1273 |
+
function hourminute($pot) {
|
1274 |
+
if (preg_match("/^[0-2][0-9]:[0-5][0-9]$/", $pot)) return $pot;
|
1275 |
+
if ('' == $pot) return date('H:i', time()+300);
|
1276 |
+
return '00:00';
|
1277 |
+
}
|
1278 |
+
|
1279 |
+
/*
|
1280 |
+
this function is both the backup scheduler and ostensibly a filter callback for saving the option.
|
1281 |
+
it is called in the register_setting for the updraft_interval, which means when the admin settings
|
1282 |
+
are saved it is called. it returns the actual result from wp_filter_nohtml_kses (a sanitization filter)
|
1283 |
+
so the option can be properly saved.
|
1284 |
+
*/
|
1285 |
+
function schedule_backup($interval) {
|
1286 |
+
//clear schedule and add new so we don't stack up scheduled backups
|
1287 |
+
wp_clear_scheduled_hook('updraft_backup');
|
1288 |
+
switch($interval) {
|
1289 |
+
case 'every4hours':
|
1290 |
+
case 'every8hours':
|
1291 |
+
case 'twicedaily':
|
1292 |
+
case 'daily':
|
1293 |
+
case 'weekly':
|
1294 |
+
case 'fortnightly':
|
1295 |
+
case 'monthly':
|
1296 |
+
$first_time = apply_filters('updraftplus_schedule_start_files', time()+30);
|
1297 |
+
wp_schedule_event($first_time, $interval, 'updraft_backup');
|
1298 |
+
break;
|
1299 |
+
}
|
1300 |
+
return wp_filter_nohtml_kses($interval);
|
1301 |
+
}
|
1302 |
+
|
1303 |
+
// Acts as a WordPress options filter
|
1304 |
+
function googledrive_clientid_checkchange($client_id) {
|
1305 |
+
if (UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token') != '' && UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token') != $client_id) {
|
1306 |
+
require_once(UPDRAFTPLUS_DIR.'/methods/googledrive.php');
|
1307 |
+
UpdraftPlus_BackupModule_googledrive::gdrive_auth_revoke(true);
|
1308 |
+
}
|
1309 |
+
return $client_id;
|
1310 |
+
}
|
1311 |
+
|
1312 |
+
function schedule_backup_database($interval) {
|
1313 |
+
//clear schedule and add new so we don't stack up scheduled backups
|
1314 |
+
wp_clear_scheduled_hook('updraft_backup_database');
|
1315 |
+
switch($interval) {
|
1316 |
+
case 'every4hours':
|
1317 |
+
case 'every8hours':
|
1318 |
+
case 'twicedaily':
|
1319 |
+
case 'daily':
|
1320 |
+
case 'weekly':
|
1321 |
+
case 'fortnightly':
|
1322 |
+
case 'monthly':
|
1323 |
+
$first_time = apply_filters('updraftplus_schedule_start_db', time()+30);
|
1324 |
+
wp_schedule_event($first_time, $interval, 'updraft_backup_database');
|
1325 |
+
break;
|
1326 |
+
}
|
1327 |
+
return wp_filter_nohtml_kses($interval);
|
1328 |
+
}
|
1329 |
+
|
1330 |
+
//wp-cron only has hourly, daily and twicedaily, so we need to add some of our own
|
1331 |
+
function modify_cron_schedules($schedules) {
|
1332 |
+
$schedules['weekly'] = array( 'interval' => 604800, 'display' => 'Once Weekly' );
|
1333 |
+
$schedules['fortnightly'] = array( 'interval' => 1209600, 'display' => 'Once Each Fortnight' );
|
1334 |
+
$schedules['monthly'] = array( 'interval' => 2592000, 'display' => 'Once Monthly' );
|
1335 |
+
$schedules['every4hours'] = array( 'interval' => 14400, 'display' => 'Every 4 hours' );
|
1336 |
+
$schedules['every8hours'] = array( 'interval' => 28800, 'display' => 'Every 8 hours' );
|
1337 |
+
return $schedules;
|
1338 |
+
}
|
1339 |
+
|
1340 |
+
function backups_dir_location() {
|
1341 |
+
if (!empty($this->backup_dir)) return $this->backup_dir;
|
1342 |
+
$updraft_dir = untrailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dir'));
|
1343 |
+
$default_backup_dir = WP_CONTENT_DIR.'/updraft';
|
1344 |
+
//if the option isn't set, default it to /backups inside the upload dir
|
1345 |
+
$updraft_dir = ($updraft_dir)?$updraft_dir:$default_backup_dir;
|
1346 |
+
//check for the existence of the dir and an enumeration preventer.
|
1347 |
+
if(!is_dir($updraft_dir) || !is_file($updraft_dir.'/index.html') || !is_file($updraft_dir.'/.htaccess')) {
|
1348 |
+
@mkdir($updraft_dir, 0775, true);
|
1349 |
+
@file_put_contents($updraft_dir.'/index.html','Nothing to see here.');
|
1350 |
+
@file_put_contents($updraft_dir.'/.htaccess','deny from all');
|
1351 |
+
}
|
1352 |
+
$this->backup_dir = $updraft_dir;
|
1353 |
+
return $updraft_dir;
|
1354 |
+
}
|
1355 |
+
|
1356 |
+
// Called via AJAX
|
1357 |
+
function updraft_ajax_handler() {
|
1358 |
+
// Test the nonce (probably not needed, since we're presumably admin-authed, but there's no harm)
|
1359 |
+
$nonce = (empty($_REQUEST['nonce'])) ? "" : $_REQUEST['nonce'];
|
1360 |
+
if (! wp_verify_nonce($nonce, 'updraftplus-credentialtest-nonce') || empty($_REQUEST['subaction'])) die('Security check');
|
1361 |
+
|
1362 |
+
if ('lastlog' == $_GET['subaction']) {
|
1363 |
+
echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_lastmessage', '(Nothing yet logged)'));
|
1364 |
+
} elseif ($_POST['subaction'] == 'credentials_test') {
|
1365 |
+
$method = (preg_match("/^[a-z0-9]+$/", $_POST['method'])) ? $_POST['method'] : "";
|
1366 |
+
|
1367 |
+
// Test the credentials, return a code
|
1368 |
+
require_once(UPDRAFTPLUS_DIR."/methods/$method.php");
|
1369 |
+
|
1370 |
+
$objname = "UpdraftPlus_BackupModule_${method}";
|
1371 |
+
if (method_exists($objname, "credentials_test")) call_user_func(array('UpdraftPlus_BackupModule_'.$method, 'credentials_test'));
|
1372 |
+
}
|
1373 |
+
|
1374 |
+
die;
|
1375 |
+
|
1376 |
+
}
|
1377 |
+
|
1378 |
+
function updraft_download_backup() {
|
1379 |
+
$type = $_POST['type'];
|
1380 |
+
$timestamp = (int)$_POST['timestamp'];
|
1381 |
+
$backup_history = $this->get_backup_history();
|
1382 |
+
$file = $backup_history[$timestamp][$type];
|
1383 |
+
$fullpath = $this->backups_dir_location().'/'.$file;
|
1384 |
+
if(!is_readable($fullpath)) {
|
1385 |
+
//if the file doesn't exist and they're using one of the cloud options, fetch it down from the cloud.
|
1386 |
+
$this->download_backup($file);
|
1387 |
+
}
|
1388 |
+
if(@is_readable($fullpath) && is_file($fullpath)) {
|
1389 |
+
$len = filesize($fullpath);
|
1390 |
+
|
1391 |
+
$filearr = explode('.',$file);
|
1392 |
+
// //we've only got zip and gz...for now
|
1393 |
+
$file_ext = array_pop($filearr);
|
1394 |
+
if($file_ext == 'zip') {
|
1395 |
+
header('Content-type: application/zip');
|
1396 |
+
} else {
|
1397 |
+
// This catches both when what was popped was 'crypt' (*-db.gz.crypt) and when it was 'gz' (unencrypted)
|
1398 |
+
header('Content-type: application/x-gzip');
|
1399 |
+
}
|
1400 |
+
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
|
1401 |
+
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
|
1402 |
+
header("Content-Length: $len;");
|
1403 |
+
if ($file_ext == 'crypt') {
|
1404 |
+
header("Content-Disposition: attachment; filename=\"".substr($file,0,-6)."\";");
|
1405 |
+
} else {
|
1406 |
+
header("Content-Disposition: attachment; filename=\"$file\";");
|
1407 |
+
}
|
1408 |
+
ob_end_flush();
|
1409 |
+
if ($file_ext == 'crypt') {
|
1410 |
+
$encryption = UpdraftPlus_Options::get_updraft_option('updraft_encryptionphrase');
|
1411 |
+
if ($encryption == "") {
|
1412 |
+
$this->error('Decryption of database failed: the database file is encrypted, but you have no encryption key entered.');
|
1413 |
+
} else {
|
1414 |
+
require_once(dirname(__FILE__).'/includes/Rijndael.php');
|
1415 |
+
$rijndael = new Crypt_Rijndael();
|
1416 |
+
$rijndael->setKey($encryption);
|
1417 |
+
$in_handle = fopen($fullpath,'r');
|
1418 |
+
$ciphertext = "";
|
1419 |
+
while (!feof ($in_handle)) {
|
1420 |
+
$ciphertext .= fread($in_handle, 16384);
|
1421 |
+
}
|
1422 |
+
fclose ($in_handle);
|
1423 |
+
print $rijndael->decrypt($ciphertext);
|
1424 |
+
}
|
1425 |
+
} else {
|
1426 |
+
readfile($fullpath);
|
1427 |
+
}
|
1428 |
+
$this->delete_local($file);
|
1429 |
+
exit; //we exit immediately because otherwise admin-ajax appends an additional zero to the end
|
1430 |
+
} else {
|
1431 |
+
echo 'Download failed. File '.$fullpath.' did not exist or was unreadable. If you delete local backups then remote retrieval may have failed.';
|
1432 |
+
}
|
1433 |
+
}
|
1434 |
+
|
1435 |
+
function download_backup($file) {
|
1436 |
+
$service = UpdraftPlus_Options::get_updraft_option('updraft_service');
|
1437 |
+
|
1438 |
+
$method_include = UPDRAFTPLUS_DIR.'/methods/'.$service.'.php';
|
1439 |
+
if (file_exists($method_include)) require_once($method_include);
|
1440 |
+
|
1441 |
+
$objname = "UpdraftPlus_BackupModule_${service}";
|
1442 |
+
if (method_exists($objname, "download")) {
|
1443 |
+
$remote_obj = new $objname;
|
1444 |
+
$remote_obj->download($file);
|
1445 |
+
} else {
|
1446 |
+
$this->error("Automatic backup restoration is not available with the method: $service.");
|
1447 |
+
}
|
1448 |
+
|
1449 |
+
}
|
1450 |
+
|
1451 |
+
function restore_backup($timestamp) {
|
1452 |
+
global $wp_filesystem;
|
1453 |
+
$backup_history = UpdraftPlus_Options::get_updraft_option('updraft_backup_history');
|
1454 |
+
if(!is_array($backup_history[$timestamp])) {
|
1455 |
+
echo '<p>This backup does not exist in the backup history - restoration aborted. Timestamp: '.$timestamp.'</p><br/>';
|
1456 |
+
return false;
|
1457 |
+
}
|
1458 |
+
|
1459 |
+
$credentials = request_filesystem_credentials("options-general.php?page=updraftplus&action=updraft_restore&backup_timestamp=$timestamp");
|
1460 |
+
WP_Filesystem($credentials);
|
1461 |
+
if ( $wp_filesystem->errors->get_error_code() ) {
|
1462 |
+
foreach ( $wp_filesystem->errors->get_error_messages() as $message )
|
1463 |
+
show_message($message);
|
1464 |
+
exit;
|
1465 |
+
}
|
1466 |
+
|
1467 |
+
//if we make it this far then WP_Filesystem has been instantiated and is functional (tested with ftpext, what about suPHP and other situations where direct may work?)
|
1468 |
+
echo '<span style="font-weight:bold">Restoration Progress</span><div id="updraft-restore-progress">';
|
1469 |
+
|
1470 |
+
$updraft_dir = $this->backups_dir_location().'/';
|
1471 |
+
foreach($backup_history[$timestamp] as $type => $file) {
|
1472 |
+
if ($type == 'nonce') continue;
|
1473 |
+
$fullpath = $updraft_dir.$file;
|
1474 |
+
if(!is_readable($fullpath) && $type != 'db') {
|
1475 |
+
$this->download_backup($file);
|
1476 |
+
}
|
1477 |
+
# Types: uploads, themes, plugins, others, db
|
1478 |
+
if(is_readable($fullpath) && $type != 'db') {
|
1479 |
+
if(!class_exists('WP_Upgrader')) require_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php');
|
1480 |
+
require_once(UPDRAFTPLUS_DIR.'/includes/updraft-restorer.php');
|
1481 |
+
$restorer = new Updraft_Restorer();
|
1482 |
+
$val = $restorer->restore_backup($fullpath, $type);
|
1483 |
+
if(is_wp_error($val)) {
|
1484 |
+
print_r($val);
|
1485 |
+
echo '</div>'; //close the updraft_restore_progress div even if we error
|
1486 |
+
return false;
|
1487 |
+
}
|
1488 |
+
}
|
1489 |
+
}
|
1490 |
+
echo '</div>'; //close the updraft_restore_progress div
|
1491 |
+
# The 'off' check is for badly configured setups - http://wordpress.org/support/topic/plugin-wp-super-cache-warning-php-safe-mode-enabled-but-safe-mode-is-off
|
1492 |
+
if(@ini_get('safe_mode') && strtolower(@ini_get('safe_mode')) != "off") {
|
1493 |
+
echo "<p>DB could not be restored because PHP safe_mode is active on your server. You will need to manually restore the file via phpMyAdmin or another method.</p><br/>";
|
1494 |
+
return false;
|
1495 |
+
}
|
1496 |
+
return true;
|
1497 |
+
}
|
1498 |
+
|
1499 |
+
//deletes the -old directories that are created when a backup is restored.
|
1500 |
+
function delete_old_dirs() {
|
1501 |
+
global $wp_filesystem;
|
1502 |
+
$credentials = request_filesystem_credentials("options-general.php?page=updraftplus&action=updraft_delete_old_dirs");
|
1503 |
+
WP_Filesystem($credentials);
|
1504 |
+
if ( $wp_filesystem->errors->get_error_code() ) {
|
1505 |
+
foreach ( $wp_filesystem->errors->get_error_messages() as $message )
|
1506 |
+
show_message($message);
|
1507 |
+
exit;
|
1508 |
+
}
|
1509 |
+
|
1510 |
+
$to_delete = array('themes-old','plugins-old','uploads-old','others-old');
|
1511 |
+
|
1512 |
+
foreach($to_delete as $name) {
|
1513 |
+
//recursively delete
|
1514 |
+
if(!$wp_filesystem->delete(WP_CONTENT_DIR.'/'.$name, true)) {
|
1515 |
+
return false;
|
1516 |
+
}
|
1517 |
+
}
|
1518 |
+
return true;
|
1519 |
+
}
|
1520 |
+
|
1521 |
+
//scans the content dir to see if any -old dirs are present
|
1522 |
+
function scan_old_dirs() {
|
1523 |
+
$dirArr = scandir(WP_CONTENT_DIR);
|
1524 |
+
foreach($dirArr as $dir) {
|
1525 |
+
if(strpos($dir,'-old') !== false) {
|
1526 |
+
return true;
|
1527 |
+
}
|
1528 |
+
}
|
1529 |
+
return false;
|
1530 |
+
}
|
1531 |
+
|
1532 |
+
|
1533 |
+
function retain_range($input) {
|
1534 |
+
$input = (int)$input;
|
1535 |
+
if($input > 0 && $input < 3650) {
|
1536 |
+
return $input;
|
1537 |
+
} else {
|
1538 |
+
return 1;
|
1539 |
+
}
|
1540 |
+
}
|
1541 |
+
|
1542 |
+
function create_backup_dir() {
|
1543 |
+
global $wp_filesystem;
|
1544 |
+
$credentials = request_filesystem_credentials("options-general.php?page=updraftplus&action=updraft_create_backup_dir");
|
1545 |
+
WP_Filesystem($credentials);
|
1546 |
+
if ( $wp_filesystem->errors->get_error_code() ) {
|
1547 |
+
foreach ( $wp_filesystem->errors->get_error_messages() as $message ) show_message($message);
|
1548 |
+
exit;
|
1549 |
+
}
|
1550 |
+
|
1551 |
+
$updraft_dir = $this->backups_dir_location();
|
1552 |
+
$default_backup_dir = WP_CONTENT_DIR.'/updraft';
|
1553 |
+
$updraft_dir = ($updraft_dir)?$updraft_dir:$default_backup_dir;
|
1554 |
+
|
1555 |
+
//chmod the backup dir to 0777. ideally we'd rather chgrp it but i'm not sure if it's possible to detect the group apache is running under (or what if it's not apache...)
|
1556 |
+
if(!$wp_filesystem->mkdir($updraft_dir, 0777)) return false;
|
1557 |
+
|
1558 |
+
return true;
|
1559 |
+
}
|
1560 |
+
|
1561 |
+
function memory_check_current() {
|
1562 |
+
# Returns in megabytes
|
1563 |
+
$memory_limit = ini_get('memory_limit');
|
1564 |
+
$memory_unit = $memory_limit[strlen($memory_limit)-1];
|
1565 |
+
$memory_limit = substr($memory_limit,0,strlen($memory_limit)-1);
|
1566 |
+
switch($memory_unit) {
|
1567 |
+
case 'K':
|
1568 |
+
$memory_limit = $memory_limit/1024;
|
1569 |
+
break;
|
1570 |
+
case 'G':
|
1571 |
+
$memory_limit = $memory_limit*1024;
|
1572 |
+
break;
|
1573 |
+
case 'M':
|
1574 |
+
//assumed size, no change needed
|
1575 |
+
break;
|
1576 |
+
}
|
1577 |
+
return $memory_limit;
|
1578 |
+
}
|
1579 |
+
|
1580 |
+
function memory_check($memory) {
|
1581 |
+
$memory_limit = $this->memory_check_current();
|
1582 |
+
return ($memory_limit >= $memory)?true:false;
|
1583 |
+
}
|
1584 |
+
|
1585 |
+
function execution_time_check($time) {
|
1586 |
+
$setting = ini_get('max_execution_time');
|
1587 |
+
return ( $setting==0 || $setting >= $time) ? true : false;
|
1588 |
+
}
|
1589 |
+
|
1590 |
+
function admin_init() {
|
1591 |
+
if(UpdraftPlus_Options::get_updraft_option('updraft_debug_mode')) {
|
1592 |
+
@ini_set('display_errors',1);
|
1593 |
+
@error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
|
1594 |
+
@ini_set('track_errors',1);
|
1595 |
+
}
|
1596 |
+
wp_enqueue_script('jquery');
|
1597 |
+
|
1598 |
+
if (UpdraftPlus_Options::user_can_manage() && UpdraftPlus_Options::get_updraft_option('updraft_service') == "googledrive" && UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid','') != '' && UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token','') == '') {
|
1599 |
+
add_action('admin_notices', array($this,'show_admin_warning_googledrive') );
|
1600 |
+
}
|
1601 |
+
|
1602 |
+
if (UpdraftPlus_Options::user_can_manage() && UpdraftPlus_Options::get_updraft_option('updraft_service') == "dropbox" && UpdraftPlus_Options::get_updraft_option('updraft_dropboxtk_request_token','') == '') {
|
1603 |
+
add_action('admin_notices', array($this,'show_admin_warning_dropbox') );
|
1604 |
+
}
|
1605 |
+
}
|
1606 |
+
|
1607 |
+
function url_start($urls,$url) {
|
1608 |
+
return ($urls) ? '<a href="http://'.$url.'">' : "";
|
1609 |
+
}
|
1610 |
+
|
1611 |
+
function url_end($urls,$url) {
|
1612 |
+
return ($urls) ? '</a>' : " (http://$url)";
|
1613 |
+
}
|
1614 |
+
|
1615 |
+
function wordshell_random_advert($urls) {
|
1616 |
+
if (defined('UPDRAFTPLUS_PREMIUM')) return "";
|
1617 |
+
$rad = rand(0,8);
|
1618 |
+
switch ($rad) {
|
1619 |
+
case 0:
|
1620 |
+
return $this->url_start($urls,'updraftplus.com')."Want more features or paid, guaranteed support? Check out UpdraftPlus.Com".$this->url_end($urls,'updraftplus.com');
|
1621 |
+
break;
|
1622 |
+
case 1:
|
1623 |
+
return "Find UpdraftPlus useful? ".$this->url_start($urls,'david.dw-perspective.org.uk/donate')."Please make a donation.".$this->url_end($urls,'david.dw-perspective.org.uk/donate');
|
1624 |
+
case 2:
|
1625 |
+
return $this->url_start($urls,'wordshell.net')."Check out WordShell".$this->url_end($urls,'www.wordshell.net')." - manage WordPress from the command line - huge time-saver";
|
1626 |
+
break;
|
1627 |
+
case 3:
|
1628 |
+
return "Want some more useful plugins? ".$this->url_start($urls,'profiles.wordpress.org/DavidAnderson/')."See my WordPress profile page for others.".$this->url_end($urls,'profiles.wordpress.org/DavidAnderson/');
|
1629 |
+
break;
|
1630 |
+
case 4:
|
1631 |
+
return $this->url_start($urls,'www.simbahosting.co.uk')."Need high-quality WordPress hosting from WordPress specialists? (Including automatic backups and 1-click installer). Get it from the creators of UpdraftPlus.".$this->url_end($urls,'www.simbahosting.co.uk');
|
1632 |
+
break;
|
1633 |
+
case 5:
|
1634 |
+
if (!defined('UPDRAFTPLUS_PREMIUM')) {
|
1635 |
+
return $this->url_start($urls,'updraftplus.com')."Need even more features and support? Check out UpdraftPlus Premium".$this->url_end($urls,'updraftplus.com');
|
1636 |
+
} else {
|
1637 |
+
return "Thanks for being an UpdraftPlus premium user. Keep visiting ".$this->url_start($urls,'www.updraftplus.com')."updraftplus.com".$this->url_end($urls,'www.updraftplus.com')." to see what's going on.";
|
1638 |
+
}
|
1639 |
+
break;
|
1640 |
+
case 6:
|
1641 |
+
return "Need custom WordPress services from experts (including bespoke development)?".$this->url_start($urls,'www.simbahosting.co.uk/s3/products-and-services/wordpress-experts/')." Get them from the creators of UpdraftPlus.".$this->url_end($urls,'www.simbahosting.co.uk/s3/products-and-services/wordpress-experts/');
|
1642 |
+
break;
|
1643 |
+
case 7:
|
1644 |
+
return $this->url_start($urls,'www.updraftplus.com')."Check out UpdraftPlus.Com for help, add-ons and support".$this->url_end($urls,'www.updraftplus.com');
|
1645 |
+
break;
|
1646 |
+
case 8:
|
1647 |
+
return "Want to say thank-you for UpdraftPlus? ".$this->url_start($urls,'updraftplus.com/shop/')." Please buy our very cheap 'no adverts' add-on.".$this->url_end($urls,'updraftplus.com/shop/');
|
1648 |
+
break;
|
1649 |
+
}
|
1650 |
+
}
|
1651 |
+
|
1652 |
+
function settings_formcontents() {
|
1653 |
+
$updraft_dir = $this->backups_dir_location();
|
1654 |
+
?>
|
1655 |
+
<table class="form-table" style="width:850px;">
|
1656 |
+
<tr>
|
1657 |
+
<th>File backup intervals:</th>
|
1658 |
+
<td><select name="updraft_interval">
|
1659 |
+
<?php
|
1660 |
+
$intervals = array ("manual" => "Manual", 'every4hours' => "Every 4 hours", 'every8hours' => "Every 8 hours", 'twicedaily' => "Every 12 hours", 'daily' => "Daily", 'weekly' => "Weekly", 'fortnightly' => "Fortnightly", 'monthly' => "Monthly");
|
1661 |
+
foreach ($intervals as $cronsched => $descrip) {
|
1662 |
+
echo "<option value=\"$cronsched\" ";
|
1663 |
+
if ($cronsched == UpdraftPlus_Options::get_updraft_option('updraft_interval','manual')) echo 'selected="selected"';
|
1664 |
+
echo ">$descrip</option>\n";
|
1665 |
+
}
|
1666 |
+
?>
|
1667 |
+
</select> <?php echo apply_filters('updraftplus_schedule_showfileconfig', '<input type="hidden" name="updraftplus_starttime_files" value="">'); ?>
|
1668 |
+
and retain this many backups: <?php
|
1669 |
+
$updraft_retain = UpdraftPlus_Options::get_updraft_option('updraft_retain', 1);
|
1670 |
+
$updraft_retain = ((int)$updraft_retain > 0) ? (int)$updraft_retain : 1;
|
1671 |
+
?> <input type="text" name="updraft_retain" value="<?php echo $updraft_retain ?>" style="width:40px;" />
|
1672 |
+
</td>
|
1673 |
+
</tr>
|
1674 |
+
<tr>
|
1675 |
+
<th>Database backup intervals:</th>
|
1676 |
+
<td><select name="updraft_interval_database">
|
1677 |
+
<?php
|
1678 |
+
foreach ($intervals as $cronsched => $descrip) {
|
1679 |
+
echo "<option value=\"$cronsched\" ";
|
1680 |
+
if ($cronsched == UpdraftPlus_Options::get_updraft_option('updraft_interval_database', UpdraftPlus_Options::get_updraft_option('updraft_interval'))) echo 'selected="selected"';
|
1681 |
+
echo ">$descrip</option>\n";
|
1682 |
+
}
|
1683 |
+
?>
|
1684 |
+
</select> <?php echo apply_filters('updraftplus_schedule_showdbconfig', '<input type="hidden" name="updraftplus_starttime_db" value="">'); ?>
|
1685 |
+
and retain this many backups: <?php
|
1686 |
+
$updraft_retain_db = UpdraftPlus_Options::get_updraft_option('updraft_retain_db', $updraft_retain);
|
1687 |
+
$updraft_retain_db = ((int)$updraft_retain_db > 0) ? (int)$updraft_retain_db : 1;
|
1688 |
+
?> <input type="text" name="updraft_retain_db" value="<?php echo $updraft_retain_db ?>" style="width:40px" />
|
1689 |
+
</td>
|
1690 |
+
</tr>
|
1691 |
+
<tr class="backup-interval-description">
|
1692 |
+
<td></td><td><p>If you would like to automatically schedule backups, choose schedules from the dropdowns above. Backups will occur at the intervals specified. If the two schedules are the same, then the two backups will take place together. If you choose "manual" then you must click the "Backup Now!" button whenever you wish a backup to occur.</p>
|
1693 |
+
<?php echo apply_filters('updraftplus_fixtime_advert', '<p><strong>To fix the time at which a backup should take place, </strong> (e.g. if your server is busy at day and you want to run overnight), <a href="http://updraftplus.com/shop/fix-time/">use the "Fix Time" add-on</a></p>'); ?>
|
1694 |
+
</td>
|
1695 |
+
</tr>
|
1696 |
+
<?php
|
1697 |
+
# The true (default value if non-existent) here has the effect of forcing a default of on.
|
1698 |
+
$include_themes = (UpdraftPlus_Options::get_updraft_option('updraft_include_themes',true)) ? 'checked="checked"' : "";
|
1699 |
+
$include_plugins = (UpdraftPlus_Options::get_updraft_option('updraft_include_plugins',true)) ? 'checked="checked"' : "";
|
1700 |
+
$include_uploads = (UpdraftPlus_Options::get_updraft_option('updraft_include_uploads',true)) ? 'checked="checked"' : "";
|
1701 |
+
$include_others = (UpdraftPlus_Options::get_updraft_option('updraft_include_others',true)) ? 'checked="checked"' : "";
|
1702 |
+
$include_others_exclude = UpdraftPlus_Options::get_updraft_option('updraft_include_others_exclude',UPDRAFT_DEFAULT_OTHERS_EXCLUDE);
|
1703 |
+
?>
|
1704 |
+
<tr>
|
1705 |
+
<th>Include in files backup:</th>
|
1706 |
+
<td>
|
1707 |
+
<input type="checkbox" name="updraft_include_plugins" value="1" <?php echo $include_plugins; ?> /> Plugins<br>
|
1708 |
+
<input type="checkbox" name="updraft_include_themes" value="1" <?php echo $include_themes; ?> /> Themes<br>
|
1709 |
+
<input type="checkbox" name="updraft_include_uploads" value="1" <?php echo $include_uploads; ?> /> Uploads<br>
|
1710 |
+
<input type="checkbox" name="updraft_include_others" value="1" <?php echo $include_others; ?> /> Any other directories found inside wp-content <?php if (is_multisite()) echo "(which on a multisite install includes users' blog contents) "; ?>- but exclude these directories: <input type="text" name="updraft_include_others_exclude" size="44" value="<?php echo htmlspecialchars($include_others_exclude); ?>"/><br>
|
1711 |
+
Include all of these, unless you are backing them up outside of UpdraftPlus. The above directories are usually everything (except for WordPress core itself which you can download afresh from WordPress.org). But if you have made customised modifications outside of these directories, you need to back them up another way. (<a href="http://wordshell.net">Use WordShell</a> for automatic backup, version control and patching).<br></td>
|
1712 |
+
</td>
|
1713 |
+
</tr>
|
1714 |
+
<tr>
|
1715 |
+
<th>Email:</th>
|
1716 |
+
<td><input type="text" style="width:260px" name="updraft_email" value="<?php echo UpdraftPlus_Options::get_updraft_option('updraft_email'); ?>" /> <br>Enter an address here to have a report sent (and the whole backup, if you choose) to it.</td>
|
1717 |
+
</tr>
|
1718 |
+
|
1719 |
+
<tr>
|
1720 |
+
<th>Database encryption phrase:</th>
|
1721 |
+
<?php
|
1722 |
+
$updraft_encryptionphrase = UpdraftPlus_Options::get_updraft_option('updraft_encryptionphrase');
|
1723 |
+
?>
|
1724 |
+
<td><input type="text" name="updraft_encryptionphrase" value="<?php echo $updraft_encryptionphrase ?>" style="width:132px" /></td>
|
1725 |
+
</tr>
|
1726 |
+
<tr class="backup-crypt-description">
|
1727 |
+
<td></td><td>If you enter text here, it is used to encrypt backups (Rijndael). <strong>Do make a separate record of it and do not lose it, or all your backups <em>will</em> be useless.</strong> Presently, only the database file is encrypted. This is also the key used to decrypt backups from this admin interface (so if you change it, then automatic decryption will not work until you change it back). You can also use the file example-decrypt.php from inside the UpdraftPlus plugin directory to decrypt manually.</td>
|
1728 |
+
</tr>
|
1729 |
+
</table>
|
1730 |
+
|
1731 |
+
<h2>Copying Your Backup To Remote Storage</h2>
|
1732 |
+
|
1733 |
+
<table class="form-table" style="width:850px;">
|
1734 |
+
<tr>
|
1735 |
+
<th>Choose your remote storage:</th>
|
1736 |
+
<td><select name="updraft_service" id="updraft-service">
|
1737 |
+
<?php
|
1738 |
+
$debug_mode = (UpdraftPlus_Options::get_updraft_option('updraft_debug_mode')) ? 'checked="checked"' : "";
|
1739 |
+
|
1740 |
+
$set = 'selected="selected"';
|
1741 |
+
|
1742 |
+
// Should be one of s3, dropbox, ftp, googledrive, email, or whatever else is added
|
1743 |
+
$active_service = UpdraftPlus_Options::get_updraft_option('updraft_service');
|
1744 |
+
|
1745 |
+
?>
|
1746 |
+
<option value="none" <?php
|
1747 |
+
if ($active_service == "none") echo $set; ?>>None</option>
|
1748 |
+
<?php
|
1749 |
+
foreach ($this->backup_methods as $method => $description) {
|
1750 |
+
echo "<option value=\"$method\"";
|
1751 |
+
if ($active_service == $method) echo ' '.$set;
|
1752 |
+
echo '>'.$description;
|
1753 |
+
echo "</option>\n";
|
1754 |
+
}
|
1755 |
+
?>
|
1756 |
+
</select></td>
|
1757 |
+
</tr>
|
1758 |
+
<?php
|
1759 |
+
foreach ($this->backup_methods as $method => $description) {
|
1760 |
+
require_once(UPDRAFTPLUS_DIR.'/methods/'.$method.'.php');
|
1761 |
+
$call_method = "UpdraftPlus_BackupModule_$method";
|
1762 |
+
call_user_func(array($call_method, 'config_print'));
|
1763 |
+
}
|
1764 |
+
?>
|
1765 |
+
</table>
|
1766 |
+
<script type="text/javascript">
|
1767 |
+
/* <![CDATA[ */
|
1768 |
+
var lastlog_lastmessage = "";
|
1769 |
+
var lastlog_sdata = {
|
1770 |
+
action: 'updraft_ajax',
|
1771 |
+
subaction: 'lastlog',
|
1772 |
+
nonce: '<?php echo wp_create_nonce('updraftplus-credentialtest-nonce'); ?>'
|
1773 |
+
};
|
1774 |
+
function updraft_showlastlog(){
|
1775 |
+
jQuery.get(ajaxurl, lastlog_sdata, function(response) {
|
1776 |
+
nexttimer = 1500;
|
1777 |
+
if (lastlog_lastmessage == response) { nexttimer = 4500; }
|
1778 |
+
window.setTimeout(function(){updraft_showlastlog()}, nexttimer);
|
1779 |
+
jQuery('#updraft_lastlogcontainer').html(response);
|
1780 |
+
lastlog_lastmessage = response;
|
1781 |
+
});
|
1782 |
+
}
|
1783 |
+
jQuery(document).ready(function() {
|
1784 |
+
jQuery('#enableexpertmode').click(function() {
|
1785 |
+
jQuery('.expertmode').fadeIn();
|
1786 |
+
return false;
|
1787 |
+
});
|
1788 |
+
<?php if (!is_writable($updraft_dir)) echo "jQuery('.backupdirrow').show();\n"; ?>
|
1789 |
+
window.setTimeout(function(){updraft_showlastlog()}, 1200);
|
1790 |
+
jQuery('.updraftplusmethod').hide();
|
1791 |
+
<?php
|
1792 |
+
if ($active_service) echo "jQuery('.${active_service}').show();";
|
1793 |
+
foreach ($this->backup_methods as $method => $description) {
|
1794 |
+
// already done: require_once(UPDRAFTPLUS_DIR.'/methods/'.$method.'.php');
|
1795 |
+
$call_method = "UpdraftPlus_BackupModule_$method";
|
1796 |
+
if (method_exists($call_method, 'config_print_javascript_onready')) call_user_func(array($call_method, 'config_print_javascript_onready'));
|
1797 |
+
}
|
1798 |
+
?>
|
1799 |
+
});
|
1800 |
+
/* ]]> */
|
1801 |
+
</script>
|
1802 |
+
<table class="form-table" style="width:850px;">
|
1803 |
+
<tr>
|
1804 |
+
<td colspan="2"><h2>Advanced / Debugging Settings</h2></td>
|
1805 |
+
</tr>
|
1806 |
+
<tr>
|
1807 |
+
<th>Debug mode:</th>
|
1808 |
+
<td><input type="checkbox" name="updraft_debug_mode" value="1" <?php echo $debug_mode; ?> /> <br>Check this to receive more information and emails on the backup process - useful if something is going wrong. You <strong>must</strong> send me this log if you are filing a bug report.</td>
|
1809 |
+
</tr>
|
1810 |
+
<tr>
|
1811 |
+
<th>Expert settings:</th>
|
1812 |
+
<td><a id="enableexpertmode" href="#">Show expert settings</a> - click this to show some further options; don't bother with this unless you have a problem or are curious.</td>
|
1813 |
+
</tr>
|
1814 |
+
<?php
|
1815 |
+
$delete_local = UpdraftPlus_Options::get_updraft_option('updraft_delete_local', 1);
|
1816 |
+
?>
|
1817 |
+
|
1818 |
+
<tr class="deletelocal expertmode" style="display:none;">
|
1819 |
+
<th>Delete local backup:</th>
|
1820 |
+
<td><input type="checkbox" name="updraft_delete_local" value="1" <?php if ($delete_local) echo 'checked="checked"'; ?>> <br>Uncheck this to prevent deletion of any superfluous backup files from your server after the backup run finishes (i.e. any files despatched remotely will also remain locally, and any files being kept locally will not be subject to the retention limits).</td>
|
1821 |
+
</tr>
|
1822 |
+
|
1823 |
+
<tr class="expertmode backupdirrow" style="display:none;">
|
1824 |
+
<th>Backup directory:</th>
|
1825 |
+
<td><input type="text" name="updraft_dir" style="width:525px" value="<?php echo htmlspecialchars($updraft_dir); ?>" /></td>
|
1826 |
+
</tr>
|
1827 |
+
<tr class="expertmode backupdirrow" style="display:none;">
|
1828 |
+
<td></td><td><?php
|
1829 |
+
|
1830 |
+
if(is_writable($updraft_dir)) {
|
1831 |
+
$dir_info = '<span style="color:green">Backup directory specified is writable, which is good.</span>';
|
1832 |
+
} else {
|
1833 |
+
$dir_info = '<span style="color:red">Backup directory specified is <b>not</b> writable, or does not exist. <span style="font-size:110%;font-weight:bold"><a href="options-general.php?page=updraftplus&action=updraft_create_backup_dir">Click here</a></span> to attempt to create the directory and set the permissions. If that is unsuccessful check the permissions on your server or change it to another directory that is writable by your web server process.</span>';
|
1834 |
+
}
|
1835 |
+
|
1836 |
+
echo $dir_info ?> This is where UpdraftPlus will write the zip files it creates initially. This directory must be writable by your web server. Typically you'll want to have it inside your wp-content folder (this is the default). <b>Do not</b> place it inside your uploads dir, as that will cause recursion issues (backups of backups of backups of...).</td>
|
1837 |
+
</tr>
|
1838 |
+
<tr>
|
1839 |
+
<td></td>
|
1840 |
+
<td>
|
1841 |
+
<?php
|
1842 |
+
$ws_ad = $this->wordshell_random_advert(1);
|
1843 |
+
if ($ws_ad) {
|
1844 |
+
?>
|
1845 |
+
<p style="margin: 10px 0; padding: 10px; font-size: 140%; background-color: lightYellow; border-color: #E6DB55; border: 1px solid; border-radius: 4px;">
|
1846 |
+
<?php echo $ws_ad; ?>
|
1847 |
+
</p>
|
1848 |
+
<?php
|
1849 |
+
}
|
1850 |
+
?>
|
1851 |
+
</td>
|
1852 |
+
</tr>
|
1853 |
+
<tr>
|
1854 |
+
<td></td>
|
1855 |
+
<td>
|
1856 |
+
<input type="hidden" name="action" value="update" />
|
1857 |
+
<input type="submit" class="button-primary" value="Save Changes" />
|
1858 |
+
</td>
|
1859 |
+
</tr>
|
1860 |
+
</table>
|
1861 |
+
<?php
|
1862 |
+
}
|
1863 |
+
|
1864 |
+
function settings_output() {
|
1865 |
+
|
1866 |
+
/*
|
1867 |
+
we use request here because the initial restore is triggered by a POSTed form. we then may need to obtain credentials
|
1868 |
+
for the WP_Filesystem. to do this WP outputs a form that we can't insert variables into (apparently). So the values are
|
1869 |
+
passed back in as GET parameters. REQUEST covers both GET and POST so this weird logic works.
|
1870 |
+
*/
|
1871 |
+
if(isset($_REQUEST['action']) && $_REQUEST['action'] == 'updraft_restore' && isset($_REQUEST['backup_timestamp'])) {
|
1872 |
+
$backup_success = $this->restore_backup($_REQUEST['backup_timestamp']);
|
1873 |
+
if(empty($this->errors) && $backup_success == true) {
|
1874 |
+
echo '<p>Restore successful!</p><br/>';
|
1875 |
+
echo '<b>Actions:</b> <a href="options-general.php?page=updraftplus&updraft_restore_success=true">Return to Updraft Configuration</a>.';
|
1876 |
+
return;
|
1877 |
+
} else {
|
1878 |
+
echo '<p>Restore failed...</p><ul>';
|
1879 |
+
foreach ($this->errors as $err) {
|
1880 |
+
echo "<li>";
|
1881 |
+
if (is_string($err)) { echo htmlspecialchars($err); } else {
|
1882 |
+
print_r($err);
|
1883 |
+
}
|
1884 |
+
echo "</li>";
|
1885 |
+
}
|
1886 |
+
echo '</ul><b>Actions:</b> <a href="options-general.php?page=updraftplus">Return to Updraft Configuration</a>.';
|
1887 |
+
return;
|
1888 |
+
}
|
1889 |
+
//uncomment the below once i figure out how i want the flow of a restoration to work.
|
1890 |
+
//echo '<b>Actions:</b> <a href="options-general.php?page=updraftplus">Return to Updraft Configuration</a>.';
|
1891 |
+
}
|
1892 |
+
$deleted_old_dirs = false;
|
1893 |
+
if(isset($_REQUEST['action']) && $_REQUEST['action'] == 'updraft_delete_old_dirs') {
|
1894 |
+
if($this->delete_old_dirs()) {
|
1895 |
+
$deleted_old_dirs = true;
|
1896 |
+
} else {
|
1897 |
+
echo '<p>Old directory removal failed for some reason. You may want to do this manually.</p><br/>';
|
1898 |
+
}
|
1899 |
+
echo '<p>Old directories successfully removed.</p><br/>';
|
1900 |
+
echo '<b>Actions:</b> <a href="options-general.php?page=updraftplus">Return to Updraft Configuration</a>.';
|
1901 |
+
return;
|
1902 |
+
}
|
1903 |
+
|
1904 |
+
if(isset($_GET['error'])) {
|
1905 |
+
$this->show_admin_warning(htmlspecialchars($_GET['error']), 'error');
|
1906 |
+
}
|
1907 |
+
if(isset($_GET['message'])) {
|
1908 |
+
$this->show_admin_warning(htmlspecialchars($_GET['message']));
|
1909 |
+
}
|
1910 |
+
|
1911 |
+
if(isset($_GET['action']) && $_GET['action'] == 'updraft_create_backup_dir') {
|
1912 |
+
if(!$this->create_backup_dir()) {
|
1913 |
+
echo '<p>Backup directory could not be created...</p><br/>';
|
1914 |
+
}
|
1915 |
+
echo '<p>Backup directory successfully created.</p><br/>';
|
1916 |
+
echo '<b>Actions:</b> <a href="options-general.php?page=updraftplus">Return to Updraft Configuration</a>.';
|
1917 |
+
return;
|
1918 |
+
}
|
1919 |
+
|
1920 |
+
if(isset($_POST['action']) && $_POST['action'] == 'updraft_backup') {
|
1921 |
+
echo '<div class="updated fade" style="max-width: 800px; font-size:140%; line-height: 140%; padding:14px; clear:left;"><strong>Schedule backup:</strong> ';
|
1922 |
+
if (wp_schedule_single_event(time()+5, 'updraft_backup_all') === false) {
|
1923 |
+
$this->log("A backup run failed to schedule");
|
1924 |
+
echo "Failed.";
|
1925 |
+
} else {
|
1926 |
+
echo "OK. Now load any page from your site to make sure the schedule can trigger.";
|
1927 |
+
$this->log("A backup run has been scheduled");
|
1928 |
+
}
|
1929 |
+
echo '</div>';
|
1930 |
+
}
|
1931 |
+
|
1932 |
+
// updraft_file_ids is not deleted
|
1933 |
+
if(isset($_POST['action']) && $_POST['action'] == 'updraft_backup_debug_all') { $this->boot_backup(true,true); }
|
1934 |
+
elseif (isset($_POST['action']) && $_POST['action'] == 'updraft_backup_debug_db') { $this->backup_db(); }
|
1935 |
+
elseif (isset($_POST['action']) && $_POST['action'] == 'updraft_wipesettings') {
|
1936 |
+
$settings = array('updraft_interval', 'updraft_interval_database', 'updraft_retain', 'updraft_retain_db', 'updraft_encryptionphrase', 'updraft_service', 'updraft_s3_login', 'updraft_s3_pass', 'updraft_s3_remote_path', 'updraft_dropbox_appkey', 'updraft_dropbox_secret', 'updraft_dropbox_folder', 'updraft_googledrive_clientid', 'updraft_googledrive_secret', 'updraft_googledrive_remotepath', 'updraft_ftp_login', 'updraft_ftp_pass', 'updraft_ftp_remote_path', 'updraft_server_address', 'updraft_dir', 'updraft_email', 'updraft_delete_local', 'updraft_debug_mode', 'updraft_include_plugins', 'updraft_include_themes', 'updraft_include_uploads', 'updraft_include_others', 'updraft_include_others_exclude', 'updraft_lastmessage', 'updraft_googledrive_clientid', 'updraft_googledrive_token', 'updraft_dropboxtk_request_token', 'updraft_dropboxtk_access_token', 'updraft_dropbox_folder', 'updraft_last_backup', 'updraft_starttime_files', 'updraft_starttime_db');
|
1937 |
+
foreach ($settings as $s) {
|
1938 |
+
UpdraftPlus_Options::delete_updraft_option($s);
|
1939 |
+
}
|
1940 |
+
$this->show_admin_warning("Your settings have been wiped.");
|
1941 |
+
}
|
1942 |
+
|
1943 |
+
?>
|
1944 |
+
<div class="wrap">
|
1945 |
+
<h1><?php echo $this->plugin_title; ?></h1>
|
1946 |
+
|
1947 |
+
Maintained by <b>David Anderson</b> (<a href="http://updraftplus.com">UpdraftPlus.Com</a> | <a href="http://david.dw-perspective.org.uk">Author Homepage</a> | <?php if (!defined('UPDRAFTPLUS_PREMIUM')) { ?><a href="http://wordshell.net">WordShell - WordPress command line</a> | <a href="http://david.dw-perspective.org.uk/donate">Donate</a> | <?php } ?><a href="http://wordpress.org/extend/plugins/updraftplus/faq/">FAQs</a> | <a href="http://profiles.wordpress.org/davidanderson/">My other WordPress plugins</a>). Version: <?php echo $this->version; ?>
|
1948 |
+
<br>
|
1949 |
+
<?php
|
1950 |
+
if(isset($_GET['updraft_restore_success'])) {
|
1951 |
+
echo "<div style=\"color:blue\">Your backup has been restored. Your old themes, uploads, and plugins directories have been retained with \"-old\" appended to their name. Remove them when you are satisfied that the backup worked properly. At this time Updraft does not automatically restore your DB. You will need to use an external tool like phpMyAdmin to perform that task.</div>";
|
1952 |
+
}
|
1953 |
+
|
1954 |
+
$ws_advert = $this->wordshell_random_advert(1);
|
1955 |
+
if ($ws_advert) { echo '<div class="updated fade" style="max-width: 800px; font-size:140%; line-height: 140%; padding:14px; clear:left;">'.$ws_advert.'</div>'; }
|
1956 |
+
|
1957 |
+
if($deleted_old_dirs) echo '<div style="color:blue">Old directories successfully deleted.</div>';
|
1958 |
+
|
1959 |
+
if(!$this->memory_check(96)) {?>
|
1960 |
+
<div style="color:orange">Your PHP memory limit is too low. UpdraftPlus attempted to raise it but was unsuccessful. This plugin may not work properly with a memory limit of less than 96 Mb (though on the other hand, it has been used successfully with a 32Mb limit - your mileage may vary, but don't blame us!). Current limit is: <?php echo $this->memory_check_current(); ?> Mb</div>
|
1961 |
+
<?php
|
1962 |
+
}
|
1963 |
+
if(!$this->execution_time_check(300)) {?>
|
1964 |
+
<div style="color:orange">Your PHP max_execution_time is less than 300 seconds. This probably means you're running in safe_mode. Either disable safe_mode or modify your php.ini to set max_execution_time to a higher number. If you do not, there is a chance Updraft will be unable to complete a backup. Present limit is: <?php echo ini_get('max_execution_time'); ?> seconds.</div>
|
1965 |
+
<?php
|
1966 |
+
}
|
1967 |
+
|
1968 |
+
if($this->scan_old_dirs()) {?>
|
1969 |
+
<div style="color:orange">You have old directories from a previous backup. Click to delete them after you have verified that the restoration worked.</div>
|
1970 |
+
<form method="post" action="<?php echo remove_query_arg(array('updraft_restore_success','action')) ?>">
|
1971 |
+
<input type="hidden" name="action" value="updraft_delete_old_dirs" />
|
1972 |
+
<input type="submit" class="button-primary" value="Delete Old Dirs" onclick="return(confirm('Are you sure you want to delete the old directories? This cannot be undone.'))" />
|
1973 |
+
</form>
|
1974 |
+
<?php
|
1975 |
+
}
|
1976 |
+
if(!empty($this->errors)) {
|
1977 |
+
foreach($this->errors as $error) {
|
1978 |
+
// ignoring severity
|
1979 |
+
echo '<div style="color:red">'.$error['error'].'</div>';
|
1980 |
+
}
|
1981 |
+
}
|
1982 |
+
?>
|
1983 |
+
|
1984 |
+
<h2 style="clear:left;">Existing Schedule And Backups</h2>
|
1985 |
+
<table class="form-table" style="float:left; clear: both; width:545px;">
|
1986 |
+
<tr>
|
1987 |
+
<?php
|
1988 |
+
$updraft_dir = $this->backups_dir_location();
|
1989 |
+
// UNIX timestamp
|
1990 |
+
$next_scheduled_backup = wp_next_scheduled('updraft_backup');
|
1991 |
+
if ($next_scheduled_backup) {
|
1992 |
+
// Convert to GMT
|
1993 |
+
$next_scheduled_backup_gmt = gmdate('Y-m-d H:i:s', $next_scheduled_backup);
|
1994 |
+
// Convert to blog time zone
|
1995 |
+
$next_scheduled_backup = get_date_from_gmt($next_scheduled_backup_gmt, 'D, F j, Y H:i T');
|
1996 |
+
} else {
|
1997 |
+
$next_scheduled_backup = 'No backups are scheduled at this time.';
|
1998 |
+
}
|
1999 |
+
|
2000 |
+
$next_scheduled_backup_database = wp_next_scheduled('updraft_backup_database');
|
2001 |
+
if (UpdraftPlus_Options::get_updraft_option('updraft_interval_database',UpdraftPlus_Options::get_updraft_option('updraft_interval')) == UpdraftPlus_Options::get_updraft_option('updraft_interval')) {
|
2002 |
+
$next_scheduled_backup_database = "Will take place at the same time as the files backup.";
|
2003 |
+
} else {
|
2004 |
+
if ($next_scheduled_backup_database) {
|
2005 |
+
// Convert to GMT
|
2006 |
+
$next_scheduled_backup_database_gmt = gmdate('Y-m-d H:i:s', $next_scheduled_backup_database);
|
2007 |
+
// Convert to blog time zone
|
2008 |
+
$next_scheduled_backup_database = get_date_from_gmt($next_scheduled_backup_database_gmt, 'D, F j, Y H:i T');
|
2009 |
+
} else {
|
2010 |
+
$next_scheduled_backup_database = 'No backups are scheduled at this time.';
|
2011 |
+
}
|
2012 |
+
}
|
2013 |
+
$current_time = get_date_from_gmt(gmdate('Y-m-d H:i:s'), 'D, F j, Y H:i T');
|
2014 |
+
$updraft_last_backup = UpdraftPlus_Options::get_updraft_option('updraft_last_backup');
|
2015 |
+
if($updraft_last_backup) {
|
2016 |
+
if ($updraft_last_backup['success']) {
|
2017 |
+
// Convert to GMT, then to blog time
|
2018 |
+
$last_backup = get_date_from_gmt(gmdate('Y-m-d H:i:s', $updraft_last_backup['backup_time']), 'D, F j, Y H:i T');
|
2019 |
+
} else {
|
2020 |
+
$last_backup = implode("<br>",$updraft_last_backup['errors']);
|
2021 |
+
}
|
2022 |
+
|
2023 |
+
$last_backup_color = ($updraft_last_backup['success']) ? 'green' : 'red';
|
2024 |
+
if (!empty($updraft_last_backup['backup_nonce'])) {
|
2025 |
+
$potential_log_file = $updraft_dir."/log.".$updraft_last_backup['backup_nonce'].".txt";
|
2026 |
+
if (is_readable($potential_log_file)) $last_backup .= "<br><a href=\"?page=updraftplus&action=downloadlog&updraftplus_backup_nonce=".$updraft_last_backup['backup_nonce']."\">Download log file</a>";
|
2027 |
+
}
|
2028 |
+
} else {
|
2029 |
+
$last_backup = 'No backup has been completed.';
|
2030 |
+
$last_backup_color = 'blue';
|
2031 |
+
}
|
2032 |
+
|
2033 |
+
if(is_writable($updraft_dir)) {
|
2034 |
+
$backup_disabled = "";
|
2035 |
+
} else {
|
2036 |
+
$backup_disabled = 'disabled="disabled"';
|
2037 |
+
}
|
2038 |
+
?>
|
2039 |
+
|
2040 |
+
<th>Time now:</th>
|
2041 |
+
<td style="color:blue"><?php echo $current_time?></td>
|
2042 |
+
</tr>
|
2043 |
+
<tr>
|
2044 |
+
<th>Next scheduled files backup:</th>
|
2045 |
+
<td style="color:blue"><?php echo $next_scheduled_backup?></td>
|
2046 |
+
</tr>
|
2047 |
+
<tr>
|
2048 |
+
<th>Next scheduled DB backup:</th>
|
2049 |
+
<td style="color:blue"><?php echo $next_scheduled_backup_database?></td>
|
2050 |
+
</tr>
|
2051 |
+
<tr>
|
2052 |
+
<th>Last backup:</th>
|
2053 |
+
<td style="color:<?php echo $last_backup_color ?>"><?php echo $last_backup?></td>
|
2054 |
+
</tr>
|
2055 |
+
</table>
|
2056 |
+
<div style="float:left; width:200px; padding-top: 40px;">
|
2057 |
+
<form method="post" action="">
|
2058 |
+
<input type="hidden" name="action" value="updraft_backup" />
|
2059 |
+
<p><input type="submit" <?php echo $backup_disabled ?> class="button-primary" value="Backup Now!" style="padding-top:2px;padding-bottom:2px;font-size:22px !important" onclick="return(confirm('This will schedule a one-time backup. To trigger the backup you should go ahead, then wait 10 seconds, then visit any page on your site. WordPress should then start the backup running in the background.'))"></p>
|
2060 |
+
</form>
|
2061 |
+
<div style="position:relative">
|
2062 |
+
<div style="position:absolute;top:0;left:0">
|
2063 |
+
<?php
|
2064 |
+
$backup_history = UpdraftPlus_Options::get_updraft_option('updraft_backup_history');
|
2065 |
+
$backup_history = (is_array($backup_history))?$backup_history:array();
|
2066 |
+
$restore_disabled = (count($backup_history) == 0) ? 'disabled="disabled"' : "";
|
2067 |
+
?>
|
2068 |
+
<input type="button" class="button-primary" <?php echo $restore_disabled ?> value="Restore" style="padding-top:2px;padding-bottom:2px;font-size:22px !important" onclick="jQuery('#backup-restore').fadeIn('slow');jQuery(this).parent().fadeOut('slow')">
|
2069 |
+
</div>
|
2070 |
+
<div style="display:none;position:absolute;top:0;left:0" id="backup-restore">
|
2071 |
+
<form method="post" action="">
|
2072 |
+
<b>Choose: </b>
|
2073 |
+
<select name="backup_timestamp" style="display:inline">
|
2074 |
+
<?php
|
2075 |
+
foreach($backup_history as $key=>$value) {
|
2076 |
+
echo "<option value='$key'>".date('Y-m-d G:i',$key)."</option>\n";
|
2077 |
+
}
|
2078 |
+
?>
|
2079 |
+
</select>
|
2080 |
+
|
2081 |
+
<input type="hidden" name="action" value="updraft_restore" />
|
2082 |
+
<input type="submit" <?php echo $restore_disabled ?> class="button-primary" value="Restore Now!" style="padding-top:7px;margin-top:5px;padding-bottom:7px;font-size:24px !important" onclick="return(confirm('Restoring from backup will replace this site\'s themes, plugins, uploads and other content directories (according to what is contained in the backup set which you select). Database restoration cannot be done through this process - you must download the database and import yourself (e.g. through PHPMyAdmin). Do you wish to continue with the restoration process?'))" />
|
2083 |
+
</form>
|
2084 |
+
</div>
|
2085 |
+
</div>
|
2086 |
+
</div>
|
2087 |
+
<br style="clear:both" />
|
2088 |
+
<table class="form-table">
|
2089 |
+
<tr>
|
2090 |
+
<th>Last backup log message:</th>
|
2091 |
+
<td id="updraft_lastlogcontainer"><?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_lastmessage', '(Nothing yet logged)')); ?></td>
|
2092 |
+
</tr>
|
2093 |
+
<tr>
|
2094 |
+
<th>Download backups and logs:</th>
|
2095 |
+
<td><a href="#" title="Click to see available backups" onclick="jQuery('.download-backups').toggle();return false;"><?php echo count($backup_history)?> available</a></td>
|
2096 |
+
</tr>
|
2097 |
+
<tr>
|
2098 |
+
<td></td><td class="download-backups" style="display:none">
|
2099 |
+
<em>Click on a button to download the corresponding file to your computer. If you are using the <a href="http://opera.com">Opera web browser</a> then you should turn Turbo mode off. <strong>Note</strong> - if you use remote storage (e.g. Amazon, Dropbox, FTP, Google Drive), then pressing a button will make UpdraftPlus try to bring a backup file back from the remote storage to your webserver, and from there to your computer. If the backup file is very big, then likely you will run out of time using this method. In that case you should get the file directly (i.e. visit Amazon S3's or Dropbox's website, etc.).</em>
|
2100 |
+
<table>
|
2101 |
+
<?php
|
2102 |
+
foreach($backup_history as $key=>$value) {
|
2103 |
+
?>
|
2104 |
+
<tr>
|
2105 |
+
<td><b><?php echo date('Y-m-d G:i',$key)?></b></td>
|
2106 |
+
<td>
|
2107 |
+
<?php if (isset($value['db'])) { ?>
|
2108 |
+
<form action="admin-ajax.php" method="post">
|
2109 |
+
<input type="hidden" name="action" value="updraft_download_backup" />
|
2110 |
+
<input type="hidden" name="type" value="db" />
|
2111 |
+
<input type="hidden" name="timestamp" value="<?php echo $key?>" />
|
2112 |
+
<input type="submit" value="Database" />
|
2113 |
+
</form>
|
2114 |
+
<?php } else { echo "(No database)"; } ?>
|
2115 |
+
</td>
|
2116 |
+
<td>
|
2117 |
+
<?php if (isset($value['plugins'])) { ?>
|
2118 |
+
<form action="admin-ajax.php" method="post">
|
2119 |
+
<input type="hidden" name="action" value="updraft_download_backup" />
|
2120 |
+
<input type="hidden" name="type" value="plugins" />
|
2121 |
+
<input type="hidden" name="timestamp" value="<?php echo $key?>" />
|
2122 |
+
<input type="submit" value="Plugins" />
|
2123 |
+
</form>
|
2124 |
+
<?php } else { echo "(No plugins)"; } ?>
|
2125 |
+
</td>
|
2126 |
+
<td>
|
2127 |
+
<?php if (isset($value['themes'])) { ?>
|
2128 |
+
<form action="admin-ajax.php" method="post">
|
2129 |
+
<input type="hidden" name="action" value="updraft_download_backup" />
|
2130 |
+
<input type="hidden" name="type" value="themes" />
|
2131 |
+
<input type="hidden" name="timestamp" value="<?php echo $key?>" />
|
2132 |
+
<input type="submit" value="Themes" />
|
2133 |
+
</form>
|
2134 |
+
<?php } else { echo "(No themes)"; } ?>
|
2135 |
+
</td>
|
2136 |
+
<td>
|
2137 |
+
<?php if (isset($value['uploads'])) { ?>
|
2138 |
+
<form action="admin-ajax.php" method="post">
|
2139 |
+
<input type="hidden" name="action" value="updraft_download_backup" />
|
2140 |
+
<input type="hidden" name="type" value="uploads" />
|
2141 |
+
<input type="hidden" name="timestamp" value="<?php echo $key?>" />
|
2142 |
+
<input type="submit" value="Uploads" />
|
2143 |
+
</form>
|
2144 |
+
<?php } else { echo "(No uploads)"; } ?>
|
2145 |
+
</td>
|
2146 |
+
<td>
|
2147 |
+
<?php if (isset($value['others'])) { ?>
|
2148 |
+
<form action="admin-ajax.php" method="post">
|
2149 |
+
<input type="hidden" name="action" value="updraft_download_backup" />
|
2150 |
+
<input type="hidden" name="type" value="others" />
|
2151 |
+
<input type="hidden" name="timestamp" value="<?php echo $key?>" />
|
2152 |
+
<input type="submit" value="Others" />
|
2153 |
+
</form>
|
2154 |
+
<?php } else { echo "(No others)"; } ?>
|
2155 |
+
</td>
|
2156 |
+
<td>
|
2157 |
+
<?php if (isset($value['nonce']) && preg_match("/^[0-9a-f]{12}$/",$value['nonce']) && is_readable($updraft_dir.'/log.'.$value['nonce'].'.txt')) { ?>
|
2158 |
+
<form action="options-general.php" method="get">
|
2159 |
+
<input type="hidden" name="action" value="downloadlog" />
|
2160 |
+
<input type="hidden" name="page" value="updraftplus" />
|
2161 |
+
<input type="hidden" name="updraftplus_backup_nonce" value="<?php echo $value['nonce']; ?>" />
|
2162 |
+
<input type="submit" value="Backup Log" />
|
2163 |
+
</form>
|
2164 |
+
<?php } else { echo "(No backup log)"; } ?>
|
2165 |
+
</td>
|
2166 |
+
</tr>
|
2167 |
+
<?php }?>
|
2168 |
+
</table>
|
2169 |
+
</td>
|
2170 |
+
</tr>
|
2171 |
+
</table>
|
2172 |
+
<?php
|
2173 |
+
if (!defined('UPDRAFTPLUS_PREMIUM') && is_multisite()) {
|
2174 |
+
?>
|
2175 |
+
<h2>UpdraftPlus Premium</h2>
|
2176 |
+
<table>
|
2177 |
+
<tr>
|
2178 |
+
<td>
|
2179 |
+
<p style="max-width:800px;">Do you need WordPress Multisite support? Please check out <a href="http://updraftplus.com">UpdraftPlus Premium</a> - and in coming weeks, it will add even more premium features. Why not support UpdraftPlus development?</p>
|
2180 |
+
</td>
|
2181 |
+
</tr>
|
2182 |
+
</table>
|
2183 |
+
<?php } ?>
|
2184 |
+
<h2>Configure Backup Contents And Schedule</h2>
|
2185 |
+
<?php UpdraftPlus_Options::options_form_begin(); ?>
|
2186 |
+
<?php $this->settings_formcontents(); ?>
|
2187 |
+
</form>
|
2188 |
+
<div style="padding-top: 40px; display:none;" class="expertmode">
|
2189 |
+
<hr>
|
2190 |
+
<h3>Debug Information And Expert Options</h3>
|
2191 |
+
<p>
|
2192 |
+
<?php
|
2193 |
+
$peak_memory_usage = memory_get_peak_usage(true)/1024/1024;
|
2194 |
+
$memory_usage = memory_get_usage(true)/1024/1024;
|
2195 |
+
echo 'Peak memory usage: '.$peak_memory_usage.' MB<br/>';
|
2196 |
+
echo 'Current memory usage: '.$memory_usage.' MB<br/>';
|
2197 |
+
echo 'PHP memory limit: '.ini_get('memory_limit').' <br/>';
|
2198 |
+
?>
|
2199 |
+
</p>
|
2200 |
+
<p style="max-width: 600px;">The buttons below will immediately execute a backup run, independently of WordPress's scheduler. If these work whilst your scheduled backups and the "Backup Now" button do absolutely nothing (i.e. not even produce a log file), then it means that your scheduler is broken. You should then disable all your other plugins, and try the " Backup Now" button. If that fails, then contact your web hosting company and ask them if they have disabled wp-cron. If it succeeds, then re-activate your other plugins one-by-one, and find the one that is the problem and report a bug to them.</p>
|
2201 |
+
|
2202 |
+
<form method="post">
|
2203 |
+
<input type="hidden" name="action" value="updraft_backup_debug_all" />
|
2204 |
+
<p><input type="submit" class="button-primary" <?php echo $backup_disabled ?> value="Debug Full Backup" onclick="return(confirm('This will cause an immediate backup. The page will stall loading until it finishes (ie, unscheduled).'))" /></p>
|
2205 |
+
</form>
|
2206 |
+
<form method="post">
|
2207 |
+
<input type="hidden" name="action" value="updraft_backup_debug_db" />
|
2208 |
+
<p><input type="submit" class="button-primary" <?php echo $backup_disabled ?> value="Debug DB Backup" onclick="return(confirm('This will cause an immediate DB backup. The page will stall loading until it finishes (ie, unscheduled). The backup may well run out of time; really this button is only helpful for checking that the backup is able to get through the initial stages, or for small WordPress sites.'))" /></p>
|
2209 |
+
</form>
|
2210 |
+
<h3>Wipe Settings</h3>
|
2211 |
+
<p style="max-width: 600px;">This button will delete all UpdraftPlus settings (but not any of your existing backups from your cloud storage). You will then need to enter all your settings again. You can also do this before deactivating/deinstalling UpdraftPlus if you wish.</p>
|
2212 |
+
<form method="post">
|
2213 |
+
<input type="hidden" name="action" value="updraft_wipesettings" />
|
2214 |
+
<p><input type="submit" class="button-primary" value="Wipe All Settings" onclick="return(confirm('This will delete all your UpdraftPlus settings - are you sure you want to do this?'))" /></p>
|
2215 |
+
</form>
|
2216 |
+
</div>
|
2217 |
+
|
2218 |
+
<script type="text/javascript">
|
2219 |
+
/* <![CDATA[ */
|
2220 |
+
jQuery(document).ready(function() {
|
2221 |
+
jQuery('#updraft-service').change(function() {
|
2222 |
+
jQuery('.updraftplusmethod').hide();
|
2223 |
+
var active_class = jQuery(this).val();
|
2224 |
+
jQuery('.'+active_class).show();
|
2225 |
+
})
|
2226 |
+
})
|
2227 |
+
jQuery(window).load(function() {
|
2228 |
+
//this is for hiding the restore progress at the top after it is done
|
2229 |
+
setTimeout('jQuery("#updraft-restore-progress").toggle(1000)',3000)
|
2230 |
+
jQuery('#updraft-restore-progress-toggle').click(function() {
|
2231 |
+
jQuery('#updraft-restore-progress').toggle(500)
|
2232 |
+
})
|
2233 |
+
})
|
2234 |
+
/* ]]> */
|
2235 |
+
</script>
|
2236 |
+
<?php
|
2237 |
+
}
|
2238 |
+
|
2239 |
+
function show_admin_warning($message, $class = "updated") {
|
2240 |
+
echo '<div id="updraftmessage" class="'.$class.' fade">'."<p>$message</p></div>";
|
2241 |
+
}
|
2242 |
+
|
2243 |
+
function show_admin_warning_unreadablelog() {
|
2244 |
+
$this->show_admin_warning('<strong>UpdraftPlus notice:</strong> The log file could not be read.');
|
2245 |
+
}
|
2246 |
+
|
2247 |
+
function show_admin_warning_dropbox() {
|
2248 |
+
$this->show_admin_warning('<strong>UpdraftPlus notice:</strong> <a href="options-general.php?page=updraftplus&action=updraftmethod-dropbox-auth&updraftplus_dropboxauth=doit">Click here to authenticate your Dropbox account (you will not be able to back up to Dropbox without it).</a>');
|
2249 |
+
}
|
2250 |
+
|
2251 |
+
function show_admin_warning_googledrive() {
|
2252 |
+
$this->show_admin_warning('<strong>UpdraftPlus notice:</strong> <a href="options-general.php?page=updraftplus&action=updraftmethod-googledrive-auth&updraftplus_googleauth=doit">Click here to authenticate your Google Drive account (you will not be able to back up to Google Drive without it).</a>');
|
2253 |
+
}
|
2254 |
+
|
2255 |
+
// Caution: $source is allowed to be an array, not just a filename
|
2256 |
+
function make_zipfile($source, $destination) {
|
2257 |
+
|
2258 |
+
// When to prefer PCL:
|
2259 |
+
// - We were asked to
|
2260 |
+
// - No zip extension present and no relevant method present
|
2261 |
+
// The zip extension check is not redundant, because method_exists segfaults some PHP installs, leading to support requests
|
2262 |
+
|
2263 |
+
// Fallback to PclZip - which my tests show is 25% slower
|
2264 |
+
if ($this->zip_preferpcl || (!extension_loaded('zip') && !method_exists('ZipArchive', 'AddFile'))) {
|
2265 |
+
if(!class_exists('PclZip')) require_once(ABSPATH.'/wp-admin/includes/class-pclzip.php');
|
2266 |
+
$zip_object = new PclZip($destination);
|
2267 |
+
$zipcode = $zip_object->create($source, PCLZIP_OPT_REMOVE_PATH, WP_CONTENT_DIR);
|
2268 |
+
if ($zipcode == 0 ) {
|
2269 |
+
$this->log("PclZip Error: ".$zip_object->errorName());
|
2270 |
+
return $zip_object->errorCode();
|
2271 |
+
} else {
|
2272 |
+
return true;
|
2273 |
+
}
|
2274 |
+
}
|
2275 |
+
|
2276 |
+
$this->existing_files = array();
|
2277 |
+
|
2278 |
+
// If the file exists, then we should grab its index of files inside, and sizes
|
2279 |
+
// Then, when we come to write a file, we should check if it's already there, and only add if it is not
|
2280 |
+
if (file_exists($destination) && is_readable($destination)) {
|
2281 |
+
$zip = new ZipArchive;
|
2282 |
+
$zip->open($destination);
|
2283 |
+
$this->log(basename($destination).": Zip file already exists, with ".$zip->numFiles." files");
|
2284 |
+
for ($i=0; $i<$zip->numFiles; $i++) {
|
2285 |
+
$si = $zip->statIndex($i);
|
2286 |
+
$name = $si['name'];
|
2287 |
+
$this->existing_files[$name] = $si['size'];
|
2288 |
+
}
|
2289 |
+
} elseif (file_exists($destination)) {
|
2290 |
+
$this->log("Zip file already exists, but is not readable; will remove: $destination");
|
2291 |
+
@unlink($destination);
|
2292 |
+
}
|
2293 |
+
|
2294 |
+
$this->zipfiles_added = 0;
|
2295 |
+
$this->zipfiles_dirbatched = array();
|
2296 |
+
$this->zipfiles_batched = array();
|
2297 |
+
|
2298 |
+
$last_error = -1;
|
2299 |
+
if (is_array($source)) {
|
2300 |
+
foreach ($source as $element) {
|
2301 |
+
$howmany = $this->makezip_recursive_add($destination, $element, basename($element), $element);
|
2302 |
+
if ($howmany < 0) {
|
2303 |
+
$last_error = $howmany;
|
2304 |
+
}
|
2305 |
+
}
|
2306 |
+
} else {
|
2307 |
+
$howmany = $this->makezip_recursive_add($destination, $source, basename($source), $source);
|
2308 |
+
if ($howmany < 0) {
|
2309 |
+
$last_error = $howmany;
|
2310 |
+
}
|
2311 |
+
}
|
2312 |
+
|
2313 |
+
// Any not yet dispatched?
|
2314 |
+
if (count($this->zipfiles_dirbatched)>0 || count($this->zipfiles_batched)>0) {
|
2315 |
+
$howmany = $this->makezip_addfiles($destination);
|
2316 |
+
if ($howmany < 0) {
|
2317 |
+
$last_error = $howmany;
|
2318 |
+
}
|
2319 |
+
}
|
2320 |
+
|
2321 |
+
if ($this->zipfiles_added > 0) {
|
2322 |
+
// ZipArchive::addFile sometimes fails
|
2323 |
+
if (filesize($destination) < 100) {
|
2324 |
+
// Retry with PclZip
|
2325 |
+
$this->log("Zip::addFile apparently failed - retrying with PclZip");
|
2326 |
+
$this->zip_preferpcl = true;
|
2327 |
+
return $this->make_zipfile($source, $destination);
|
2328 |
+
}
|
2329 |
+
return true;
|
2330 |
+
} else {
|
2331 |
+
return $last_error;
|
2332 |
+
}
|
2333 |
+
|
2334 |
+
}
|
2335 |
+
|
2336 |
+
// Q. Why don't we only open and close the zip file just once?
|
2337 |
+
// A. Because apparently PHP doesn't write out until the final close, and it will return an error if anything file has vanished in the meantime. So going directory-by-directory reduces our chances of hitting an error if the filesystem is changing underneath us (which is very possible if dealing with e.g. 1Gb of files)
|
2338 |
+
|
2339 |
+
// We batch up the files, rather than do them one at a time. So we are more efficient than open,one-write,close.
|
2340 |
+
function makezip_addfiles($zipfile) {
|
2341 |
+
$zip = new ZipArchive();
|
2342 |
+
if (file_exists($zipfile)) {
|
2343 |
+
$opencode = $zip->open($zipfile);
|
2344 |
+
} else {
|
2345 |
+
$opencode = $zip->open($zipfile, ZIPARCHIVE::CREATE);
|
2346 |
+
}
|
2347 |
+
if ($opencode !== true) return array($opencode, 0);
|
2348 |
+
// Make sure all directories are created before we start creating files
|
2349 |
+
while ($dir = array_pop($this->zipfiles_dirbatched)) {
|
2350 |
+
$zip->addEmptyDir($dir);
|
2351 |
+
}
|
2352 |
+
foreach ($this->zipfiles_batched as $file => $add_as) {
|
2353 |
+
if (!isset($this->existing_files[$add_as]) || $this->existing_files[$add_as] != filesize($file)) {
|
2354 |
+
$zip->addFile($file, $add_as);
|
2355 |
+
}
|
2356 |
+
$this->zipfiles_added++;
|
2357 |
+
if ($this->zipfiles_added % 100 == 0) $this->log("Zip: ".basename($zipfile).": ".$this->zipfiles_added." files added (size: ".round(filesize($zipfile)/1024,1)." Kb)");
|
2358 |
+
}
|
2359 |
+
// Reset the array
|
2360 |
+
$this->zipfiles_batched = array();
|
2361 |
+
return $zip->close();
|
2362 |
+
}
|
2363 |
+
|
2364 |
+
// This function recursively packs the zip, dereferencing symlinks but packing into a single-parent tree for universal unpacking
|
2365 |
+
function makezip_recursive_add($zipfile, $fullpath, $use_path_when_storing, $original_fullpath) {
|
2366 |
+
|
2367 |
+
// De-reference
|
2368 |
+
$fullpath = realpath($fullpath);
|
2369 |
+
|
2370 |
+
// Is the place we've ended up above the original base? That leads to infinite recursion
|
2371 |
+
if (($fullpath !== $original_fullpath && strpos($original_fullpath, $fullpath) === 0) || ($original_fullpath == $fullpath && strpos($use_path_when_storing, '/') !== false) ) {
|
2372 |
+
$this->log("Infinite recursion: symlink lead us to $fullpath, which is within $original_fullpath");
|
2373 |
+
$this->error("Infinite recursion: consult your log for more information");
|
2374 |
+
return false;
|
2375 |
+
}
|
2376 |
+
|
2377 |
+
if(is_file($fullpath)) {
|
2378 |
+
if (is_readable($fullpath)) {
|
2379 |
+
$key = $use_path_when_storing.'/'.basename($fullpath);
|
2380 |
+
$this->zipfiles_batched[$fullpath] = $use_path_when_storing.'/'.basename($fullpath);
|
2381 |
+
@touch($zipfile);
|
2382 |
+
} else {
|
2383 |
+
$this->log("$fullpath: unreadable file");
|
2384 |
+
$this->error("$fullpath: unreadable file");
|
2385 |
+
}
|
2386 |
+
} elseif (is_dir($fullpath)) {
|
2387 |
+
if (!isset($this->existing_files[$use_path_when_storing])) $this->zipfiles_dirbatched[] = $use_path_when_storing;
|
2388 |
+
if (!$dir_handle = @opendir($fullpath)) {
|
2389 |
+
$this->log("Failed to open directory: $fullpath");
|
2390 |
+
$this->error("Failed to open directory: $fullpath");
|
2391 |
+
return;
|
2392 |
+
}
|
2393 |
+
while ($e = readdir($dir_handle)) {
|
2394 |
+
if ($e != '.' && $e != '..') {
|
2395 |
+
if (is_link($fullpath.'/'.$e)) {
|
2396 |
+
$deref = realpath($fullpath.'/'.$e);
|
2397 |
+
if (is_file($deref)) {
|
2398 |
+
if (is_readable($deref)) {
|
2399 |
+
$this->zipfiles_batched[$deref] = $use_path_when_storing.'/'.$e;
|
2400 |
+
@touch($zipfile);
|
2401 |
+
} else {
|
2402 |
+
$this->log("$deref: unreadable file");
|
2403 |
+
$this->error("$deref: unreadable file");
|
2404 |
+
}
|
2405 |
+
} elseif (is_dir($deref)) {
|
2406 |
+
$this->makezip_recursive_add($zipfile, $deref, $use_path_when_storing.'/'.$e, $original_fullpath);
|
2407 |
+
}
|
2408 |
+
} elseif (is_file($fullpath.'/'.$e)) {
|
2409 |
+
if (is_readable($fullpath.'/'.$e)) {
|
2410 |
+
$this->zipfiles_batched[$fullpath.'/'.$e] = $use_path_when_storing.'/'.$e;
|
2411 |
+
@touch($zipfile);
|
2412 |
+
} else {
|
2413 |
+
$this->log("$fullpath/$e: unreadable file");
|
2414 |
+
$this->error("$fullpath/$e: unreadable file");
|
2415 |
+
}
|
2416 |
+
} elseif (is_dir($fullpath.'/'.$e)) {
|
2417 |
+
// no need to addEmptyDir here, as it gets done when we recurse
|
2418 |
+
$this->makezip_recursive_add($zipfile, $fullpath.'/'.$e, $use_path_when_storing.'/'.$e, $original_fullpath);
|
2419 |
+
}
|
2420 |
+
}
|
2421 |
+
}
|
2422 |
+
closedir($dir_handle);
|
2423 |
+
}
|
2424 |
+
|
2425 |
+
// We don't want to touch the zip file on every single file, so we batch them up
|
2426 |
+
// We go every 25 files, because if you wait too much longer, the contents may have changed from under you
|
2427 |
+
// And for some redundancy (redundant because of the touches going on anyway), we try to touch the file after 20 seconds, to help with the "recently modified" check on resumption (we saw a case where the file went for 155 seconds without being touched and so the other runner was not detected)
|
2428 |
+
if (count($this->zipfiles_batched) > 25 || (file_exists($zipfile) && ((time()-filemtime($zipfile)) > 20) )) {
|
2429 |
+
$ret = $this->makezip_addfiles($zipfile);
|
2430 |
+
} else {
|
2431 |
+
$ret = true;
|
2432 |
+
}
|
2433 |
+
|
2434 |
+
return $ret;
|
2435 |
+
|
2436 |
+
}
|
2437 |
+
|
2438 |
+
}
|
2439 |
+
|
2440 |
+
|
2441 |
+
?>
|
updraftplus.php
CHANGED
@@ -3,11 +3,11 @@
|
|
3 |
Plugin Name: UpdraftPlus - Backup/Restore
|
4 |
Plugin URI: http://wordpress.org/extend/plugins/updraftplus
|
5 |
Description: Backup and restore: your content and database can be automatically backed up to Amazon S3, Dropbox, Google Drive, FTP or email, on separate schedules.
|
6 |
-
Author: David Anderson
|
7 |
-
Version: 1.
|
8 |
Donate link: http://david.dw-perspective.org.uk/donate
|
9 |
License: GPLv3 or later
|
10 |
-
Author URI: http://
|
11 |
*/
|
12 |
|
13 |
/*
|
@@ -15,6 +15,7 @@ TODO
|
|
15 |
//Put in old-WP-version warning, and point them to where they can get help
|
16 |
//Add SFTP, Box.Net, SugarSync and Microsoft Skydrive support??
|
17 |
//The restorer has a hard-coded wp-content - fix
|
|
|
18 |
//Button for wiping files. Also auto-wipe on de-activate/de-install.
|
19 |
//Change DB encryption to not require whole gzip in memory (twice)
|
20 |
//improve error reporting / pretty up return messages in admin area. One thing: have a "backup is now finished" flag. Otherwise with the resuming things get ambiguous/confusing. See http://wordpress.org/support/topic/backup-status - user was not aware that backup completely failed. Maybe a "backup status" field for each nonce that gets updated? (Even via AJAX?)
|
@@ -22,29 +23,21 @@ TODO
|
|
22 |
//Should make clear in dashboard what is a non-fatal error (i.e. can be retried) - leads to unnecessary bug reports
|
23 |
// Move the inclusion, cloud and retention data into the backup job (i.e. don't read current config, make it an attribute of each job). In fact, everything should be. So audit all code for where get_option is called inside a backup run: it shouldn't happen.
|
24 |
// Should we resume if the only errors were upon deletion (i.e. the backup itself was fine?) Presently we do, but it displays errors for the user to confuse them. Perhaps better to make pruning a separate scheuled task??
|
|
|
25 |
// Warn the user if their zip-file creation is slooowww...
|
26 |
// Create a "Want Support?" button/console, that leads them through what is needed, and performs some basic tests...
|
27 |
// Resuming partial FTP uploads
|
|
|
28 |
// Provide backup/restoration for UpdraftPlus's settings, to allow 'bootstrap' on a fresh WP install - some kind of single-use code which a remote UpdraftPlus can use to authenticate
|
29 |
// Multiple jobs
|
30 |
-
// Expert setting: force PCLZip
|
31 |
-
// Don't stop at 10 retries if something useful is still measurably being done (in particular, chunked uploads are proceeding - set a flag to indicate "try it again")
|
32 |
-
// Change FTP to use SSL by default
|
33 |
-
// Multisite add-on should allow restoring of each blog individually
|
34 |
-
// Tweak random_advert to not show the same one twice
|
35 |
// When looking for files to delete, is the current encryption setting used? Should not be.
|
36 |
// Create single zip, containing even WordPress itself
|
37 |
-
// Have something reap any remaining .tmp files, e.g. once a week
|
38 |
// When a new backup starts, AJAX-update the 'Last backup' display in the admin page.
|
39 |
// Remove the recurrence of admin notices when settings are saved due to _wp_referer
|
40 |
-
// Auto-detect what the real execution time is (max_execution_time is just one of the upper limits, there can be others, some insivible directly), and tweak our resumption time accordingly
|
41 |
-
//http://w-shadow.com/blog/2010/09/02/automatic-updates-for-any-plugin/
|
42 |
-
// Specify the exact time to run the backup (useful if you have big site, using a lot of CPU)
|
43 |
|
44 |
Encrypt filesystem, if memory allows (and have option for abort if not); split up into multiple zips when needed
|
45 |
// Does not delete old custom directories upon a restore?
|
46 |
// Re-do making of zip files to allow resumption (every x files, store the state in a transient)
|
47 |
-
// New sub-module to verify that the backups are there, independently of backup thread
|
48 |
*/
|
49 |
|
50 |
/* Portions copyright 2010 Paul Kehrer
|
@@ -70,24 +63,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
70 |
// 15 minutes
|
71 |
@set_time_limit(900);
|
72 |
|
73 |
-
define('UPDRAFTPLUS_DIR', dirname(__FILE__));
|
74 |
-
define('UPDRAFTPLUS_URL', plugins_url('', __FILE__));
|
75 |
-
define('UPDRAFT_DEFAULT_OTHERS_EXCLUDE','upgrade,cache,updraft,index.php,backup,backups');
|
76 |
-
// This is used in various places, based on our assumption of the maximum time any job should take. May need lengthening in future if we get reports which show enormous sets hitting the limit.
|
77 |
-
// Also one section requires at least 1% progress each run, so on a 5-minute schedule, that equals just under 9 hours - then an extra allowance takes it just over
|
78 |
-
define('UPDRAFT_TRANSTIME', 3600*9+5);
|
79 |
-
|
80 |
-
// Load add-ons
|
81 |
-
if (is_file(UPDRAFTPLUS_DIR.'/premium.php')) require_once(UPDRAFTPLUS_DIR.'/premium.php');
|
82 |
-
|
83 |
-
if ($dir_handle = @opendir(UPDRAFTPLUS_DIR.'/addons')) {
|
84 |
-
while ($e = readdir($dir_handle)) {
|
85 |
-
if (is_file(UPDRAFTPLUS_DIR.'/addons/'.$e) && preg_match('/\.php$/', $e)) {
|
86 |
-
include_once(UPDRAFTPLUS_DIR.'/addons/'.$e);
|
87 |
-
}
|
88 |
-
}
|
89 |
-
}
|
90 |
-
|
91 |
if (!isset($updraftplus)) $updraftplus = new UpdraftPlus();
|
92 |
|
93 |
if (!$updraftplus->memory_check(192)) {
|
@@ -95,12 +70,17 @@ if (!$updraftplus->memory_check(192)) {
|
|
95 |
@ini_set('memory_limit', '192M'); //up the memory limit for large backup files
|
96 |
}
|
97 |
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
if (!class_exists('UpdraftPlus_Options')) require_once(UPDRAFTPLUS_DIR.'/options.php');
|
99 |
|
100 |
class UpdraftPlus {
|
101 |
|
102 |
-
var $version;
|
103 |
-
|
104 |
var $plugin_title = 'UpdraftPlus Backup/Restore';
|
105 |
|
106 |
// Choices will be shown in the admin menu in the order used here
|
@@ -125,29 +105,8 @@ class UpdraftPlus {
|
|
125 |
|
126 |
var $jobdata;
|
127 |
|
128 |
-
// Used to schedule resumption attempts beyond the tenth, if needed
|
129 |
-
var $current_resumption;
|
130 |
-
var $newresumption_scheduled = false;
|
131 |
-
|
132 |
-
var $zipfiles_added;
|
133 |
-
var $zipfiles_existingfiles;
|
134 |
-
var $zipfiles_dirbatched;
|
135 |
-
var $zipfiles_batched;
|
136 |
-
|
137 |
-
var $zip_preferpcl = false;
|
138 |
-
|
139 |
function __construct() {
|
140 |
-
|
141 |
// Initialisation actions - takes place on plugin load
|
142 |
-
|
143 |
-
if ($fp = fopen( __FILE__, 'r')) {
|
144 |
-
$file_data = fread( $fp, 1024 );
|
145 |
-
if (preg_match("/Version: ([\d\.]+)(\r|\n)/", $file_data, $matches)) {
|
146 |
-
$this->version = $matches[1];
|
147 |
-
}
|
148 |
-
fclose( $fp );
|
149 |
-
}
|
150 |
-
|
151 |
# Create admin page
|
152 |
add_action('admin_init', array($this, 'admin_init'));
|
153 |
add_action('updraft_backup', array($this,'backup_files'));
|
@@ -156,13 +115,13 @@ class UpdraftPlus {
|
|
156 |
add_action('updraft_backup_all', array($this,'backup_all'));
|
157 |
# this is our runs-after-backup event, whose purpose is to see if it succeeded or failed, and resume/mom-up etc.
|
158 |
add_action('updraft_backup_resume', array($this,'backup_resume'), 10, 3);
|
|
|
159 |
add_action('wp_ajax_updraft_download_backup', array($this, 'updraft_download_backup'));
|
160 |
add_action('wp_ajax_updraft_ajax', array($this, 'updraft_ajax_handler'));
|
161 |
# http://codex.wordpress.org/Plugin_API/Filter_Reference/cron_schedules
|
162 |
add_filter('cron_schedules', array($this,'modify_cron_schedules'));
|
163 |
add_filter('plugin_action_links', array($this, 'plugin_action_links'), 10, 2);
|
164 |
add_action('init', array($this, 'handle_url_actions'));
|
165 |
-
|
166 |
}
|
167 |
|
168 |
// Handle actions passed on to method plugins; e.g. Google OAuth 2.0 - ?page=updraftplus&action=updraftmethod-googledrive-auth
|
@@ -197,8 +156,6 @@ class UpdraftPlus {
|
|
197 |
array_unshift($links, $settings_link);
|
198 |
$settings_link = '<a href="http://david.dw-perspective.org.uk/donate">'.__("Donate","UpdraftPlus").'</a>';
|
199 |
array_unshift($links, $settings_link);
|
200 |
-
$settings_link = '<a href="http://updraftplus.com">'.__("Add-Ons / Pro Support","UpdraftPlus").'</a>';
|
201 |
-
array_unshift($links, $settings_link);
|
202 |
}
|
203 |
return $links;
|
204 |
}
|
@@ -218,14 +175,7 @@ class UpdraftPlus {
|
|
218 |
$this->opened_log_time = microtime(true);
|
219 |
$this->log("Opened log file at time: ".date('r'));
|
220 |
global $wp_version;
|
221 |
-
$
|
222 |
-
// method_exists causes some faulty PHP installations to segfault, leading to support requests
|
223 |
-
if (version_compare(phpversion(), '5.2.0', '>=') && extension_loaded('zip')) {
|
224 |
-
$logline .= 'Y';
|
225 |
-
} else {
|
226 |
-
$logline .= (method_exists('ZipArchive', 'addFile')) ? "Y" : "N";
|
227 |
-
}
|
228 |
-
$this->log($logline);
|
229 |
}
|
230 |
|
231 |
# Logs the given line, adding (relative) time stamp and newline
|
@@ -234,28 +184,6 @@ class UpdraftPlus {
|
|
234 |
UpdraftPlus_Options::update_updraft_option("updraft_lastmessage", $line." (".date('M d H:i:s').")");
|
235 |
}
|
236 |
|
237 |
-
// This function is used by cloud methods to provide standardised logging, but more importantly to help us detect that meaningful activity took place during a resumption run, so that we can schedule further resumptions if it is worthwhile
|
238 |
-
function record_uploaded_chunk($percent, $extra) {
|
239 |
-
// Log it
|
240 |
-
$service = $this->jobdata_get('service');
|
241 |
-
$log = ucfirst($service)." chunked upload: $percent % uploaded";
|
242 |
-
if ($extra) $log .= " ($extra)";
|
243 |
-
$this->log($log);
|
244 |
-
// If we are on an 'overtime' resumption run, and we are still meainingfully uploading, then schedule a new resumption
|
245 |
-
// Our definition of meaningful is that we must maintain an overall average of at least 1% per run, after allowing 9 runs for everything else to get going
|
246 |
-
// i.e. Max 109 runs = 545 minutes = 9 hrs 05
|
247 |
-
// If they get 2 minutes on each run, and the file is 1Gb, then that equals 10.2Mb/120s = minimum 87Kb/s upload speed required
|
248 |
-
|
249 |
-
if ($this->current_resumption >= 9 && $this->newresumption_scheduled == false && $percent > ( $this->current_resumption - 9)) {
|
250 |
-
$resume_interval = $this->jobdata_get('resume_interval');
|
251 |
-
if (!is_numeric($resume_interval) || $resume_interval<200) { $resume_interval = 200; }
|
252 |
-
$schedule_for = time()+$resume_interval;
|
253 |
-
$this->newresumption_scheduled = $schedule_for;
|
254 |
-
$this->log("This is resumption ".$this->current_resumption.", but meaningful uploading is still taking place; so a new one will be scheduled");
|
255 |
-
wp_schedule_single_event($schedule_for, 'updraft_backup_resume', array($this->current_resumption + 1, $this->nonce, $this->backup_time));
|
256 |
-
}
|
257 |
-
}
|
258 |
-
|
259 |
function backup_resume($resumption_no, $bnonce, $btime) {
|
260 |
|
261 |
@ignore_user_abort(true);
|
@@ -269,22 +197,16 @@ class UpdraftPlus {
|
|
269 |
}
|
270 |
|
271 |
$this->log("Backup run: resumption=$resumption_no, nonce=$bnonce, begun at=$btime");
|
272 |
-
$this->current_resumption = $resumption_no;
|
273 |
|
274 |
// Schedule again, to run in 5 minutes again, in case we again fail
|
275 |
-
|
276 |
-
$resume_interval = $this->jobdata_get('resume_interval');
|
277 |
-
if (!is_numeric($resume_interval) || $resume_interval<200) $resume_interval = 200;
|
278 |
-
|
279 |
// A different argument than before is needed otherwise the event is ignored
|
280 |
$next_resumption = $resumption_no+1;
|
281 |
if ($next_resumption < 10) {
|
282 |
$this->log("Scheduling a resumption ($next_resumption) in case this run gets aborted");
|
283 |
-
$
|
284 |
-
wp_schedule_single_event($schedule_for, 'updraft_backup_resume', array($next_resumption, $bnonce, $btime));
|
285 |
-
$this->newresumption_scheduled = $schedule_for;
|
286 |
} else {
|
287 |
-
$this->log("The current run is our tenth attempt - will not schedule a further attempt
|
288 |
}
|
289 |
|
290 |
// This should be always called; if there were no files in this run, it returns us an empty array
|
@@ -306,7 +228,7 @@ class UpdraftPlus {
|
|
306 |
$backup_database = $this->jobdata_get('backup_database');
|
307 |
|
308 |
// The transient is read and written below (instead of using the existing variable) so that we can copy-and-paste this part as needed.
|
309 |
-
if ($backup_database == "begun" || $backup_database == "finished" || $backup_database ==
|
310 |
if ($backup_database == "begun") {
|
311 |
if ($resumption_no > 0) {
|
312 |
$this->log("Resuming creation of database dump");
|
@@ -334,7 +256,7 @@ class UpdraftPlus {
|
|
334 |
if (isset($our_files['db']) && !preg_match("/\.crypt$/", $our_files['db'])) {
|
335 |
$our_files['db'] = $this->encrypt_file($our_files['db']);
|
336 |
$this->save_backup_history($our_files);
|
337 |
-
|
338 |
}
|
339 |
|
340 |
foreach ($our_files as $key => $file) {
|
@@ -366,7 +288,6 @@ class UpdraftPlus {
|
|
366 |
$this->cloud_backup($undone_files);
|
367 |
|
368 |
$this->log("Resume backup ($bnonce, $resumption_no): finish run");
|
369 |
-
if (is_array($our_files)) $this->save_last_backup($our_files);
|
370 |
$this->backup_finish($next_resumption, true, true, $resumption_no);
|
371 |
|
372 |
}
|
@@ -455,10 +376,6 @@ class UpdraftPlus {
|
|
455 |
// Save what *should* be done, to make it resumable from this point on
|
456 |
if ($backup_database) $this->jobdata_set("backup_database", "begun");
|
457 |
if ($backup_files) $this->jobdata_set("backup_files", "begun");
|
458 |
-
$this->jobdata_set('service', UpdraftPlus_Options::get_updraft_option('updraft_service'));
|
459 |
-
|
460 |
-
// This can be adapted if we see a need
|
461 |
-
$this->jobdata_set('resume_interval', 300);
|
462 |
|
463 |
// Everthing is now set up; now go
|
464 |
$this->backup_resume(0, $this->nonce, $this->backup_time);
|
@@ -521,7 +438,7 @@ class UpdraftPlus {
|
|
521 |
if (empty($this->errors)) {
|
522 |
$send_an_email = true;
|
523 |
$final_message = "The backup apparently succeeded and is now complete";
|
524 |
-
} elseif ($
|
525 |
$send_an_email = true;
|
526 |
$final_message = "The backup attempt has finished, apparently unsuccesfully";
|
527 |
} else {
|
@@ -567,11 +484,11 @@ class UpdraftPlus {
|
|
567 |
$backup_files = $this->jobdata_get("backup_files");
|
568 |
$backup_db = $this->jobdata_get("backup_database");
|
569 |
|
570 |
-
if ($backup_files == "finished" && ( $backup_db == "finished" || $backup_db ==
|
571 |
$backup_contains = "Files and database";
|
572 |
} elseif ($backup_files == "finished") {
|
573 |
$backup_contains = ($backup_db == "begun") ? "Files (database backup has not completed)" : "Files only (database was not part of this particular schedule)";
|
574 |
-
} elseif ($backup_db == "finished" || $backup_db ==
|
575 |
$backup_contains = ($backup_files == "begun") ? "Database (files backup has not completed)" : "Database only (files were not part of this particular schedule)";
|
576 |
} else {
|
577 |
$backup_contains = "Unknown/unexpected error - please raise a support request";
|
@@ -602,13 +519,12 @@ class UpdraftPlus {
|
|
602 |
}
|
603 |
// Delete local files immediately if the option is set
|
604 |
// Where we are only backing up locally, only the "prune" function should do deleting
|
605 |
-
if (
|
606 |
}
|
607 |
|
608 |
// Dispatch to the relevant function
|
609 |
function cloud_backup($backup_array) {
|
610 |
-
|
611 |
-
$service = $this->jobdata_get('service');
|
612 |
$this->log("Cloud backup selection: ".$service);
|
613 |
@set_time_limit(900);
|
614 |
|
@@ -631,8 +547,8 @@ class UpdraftPlus {
|
|
631 |
}
|
632 |
}
|
633 |
|
634 |
-
function prune_file($
|
635 |
-
$this->log("Delete this file: $dofile, service=$
|
636 |
$fullpath = $this->backups_dir_location().'/'.$dofile;
|
637 |
// delete it if it's locally available
|
638 |
if (file_exists($fullpath)) {
|
@@ -645,10 +561,10 @@ class UpdraftPlus {
|
|
645 |
}
|
646 |
|
647 |
// Carries out retain behaviour. Pass in a valid S3 or FTP object and path if relevant.
|
648 |
-
function prune_retained_backups($
|
649 |
|
650 |
// If they turned off deletion on local backups, then there is nothing to do
|
651 |
-
if (UpdraftPlus_Options::get_updraft_option('updraft_delete_local') == 0 && $
|
652 |
$this->log("Prune old backups from local store: nothing to do, since the user disabled local deletion and we are using local backups");
|
653 |
return;
|
654 |
}
|
@@ -682,7 +598,7 @@ class UpdraftPlus {
|
|
682 |
if ($db_backups_found > $updraft_retain_db) {
|
683 |
$this->log("$backup_datestamp: over retain limit ($updraft_retain_db); will delete this database");
|
684 |
$dofile = $backup_to_examine['db'];
|
685 |
-
if (!empty($dofile)) $this->prune_file($
|
686 |
unset($backup_to_examine['db']);
|
687 |
}
|
688 |
}
|
@@ -696,7 +612,7 @@ class UpdraftPlus {
|
|
696 |
$file3 = isset($backup_to_examine['uploads']) ? $backup_to_examine['uploads'] : "";
|
697 |
$file4 = isset($backup_to_examine['others']) ? $backup_to_examine['others'] : "";
|
698 |
foreach (array($file, $file2, $file3, $file4) as $dofile) {
|
699 |
-
if (!empty($dofile)) $this->prune_file($
|
700 |
}
|
701 |
unset($backup_to_examine['plugins']);
|
702 |
unset($backup_to_examine['themes']);
|
@@ -738,24 +654,6 @@ class UpdraftPlus {
|
|
738 |
return true;
|
739 |
}
|
740 |
|
741 |
-
function reschedule($how_far_ahead) {
|
742 |
-
// Reschedule - remove presently scheduled event
|
743 |
-
wp_clear_scheduled_hook('updraft_backup_resume', array($this->current_resumption + 1, $this->nonce, $this->backup_time));
|
744 |
-
// Add new event
|
745 |
-
if ($how_far_ahead < 200) $how_far_ahead=200;
|
746 |
-
$schedule_for = time() + $how_far_ahead;
|
747 |
-
wp_schedule_single_event($schedule_for, 'updraft_backup_resume', array($this->current_resumption + 1, $this->nonce, $this->backup_time));
|
748 |
-
$this->newresumption_scheduled = $schedule_for;
|
749 |
-
}
|
750 |
-
|
751 |
-
function increase_resume_and_reschedule($howmuch = 120) {
|
752 |
-
$resume_interval = $this->jobdata_get('resume_interval');
|
753 |
-
if (!is_numeric($resume_interval) || $resume_interval<200) { $resume_interval = 200; }
|
754 |
-
if ($this->newresumption_scheduled != false) $this->reschedule($resume_interval+$howmuch);
|
755 |
-
$this->jobdata_set('resume_interval', $resume_interval+$howmuch);
|
756 |
-
$this->log("To decrease the likelihood of overlaps, increasing resumption interval to: ".($resume_interval+$howmuch));
|
757 |
-
}
|
758 |
-
|
759 |
function create_zip($create_from_dir, $whichone, $create_in_dir, $backup_file_basename) {
|
760 |
// Note: $create_from_dir can be an array or a string
|
761 |
@set_time_limit(900);
|
@@ -775,21 +673,19 @@ class UpdraftPlus {
|
|
775 |
$zip_name = $full_path.'.tmp';
|
776 |
$time_now = time();
|
777 |
$time_mod = (int)@filemtime($zip_name);
|
778 |
-
if (file_exists($zip_name) && $time_mod>100 && ($time_now-$time_mod)<
|
779 |
$file_size = filesize($zip_name);
|
780 |
-
$this->log("Terminate: the temporary file $zip_name already exists, and was modified within the last
|
781 |
-
$this->increase_resume_and_reschedule(120);
|
782 |
die;
|
783 |
-
} elseif (file_exists($zip_name)) {
|
784 |
-
$this->log("File exists ($zip_name), but was apparently not modified within the last 30 seconds, so we assume that any previous run has now terminated (time_mod=$time_mod, time_now=$time_now, diff=".($time_now-$time_mod).")");
|
785 |
}
|
786 |
|
|
|
|
|
787 |
$microtime_start = microtime(true);
|
788 |
# The paths in the zip should then begin with '$whichone', having removed WP_CONTENT_DIR from the front
|
789 |
-
|
790 |
-
|
791 |
-
$this->
|
792 |
-
$this->error("Could not create $whichone zip: code $zipcode. Consult the log file for more information.");
|
793 |
return false;
|
794 |
} else {
|
795 |
rename($full_path.'.tmp', $full_path);
|
@@ -807,15 +703,17 @@ class UpdraftPlus {
|
|
807 |
|
808 |
if(!$this->backup_time) $this->backup_time_nonce();
|
809 |
|
|
|
|
|
810 |
$updraft_dir = $this->backups_dir_location();
|
811 |
if(!is_writable($updraft_dir)) {
|
812 |
-
$this->log(
|
813 |
-
$this->error(
|
814 |
return array();
|
815 |
}
|
816 |
|
817 |
//get the blog name and rip out all non-alphanumeric chars other than _
|
818 |
-
$blog_name = str_replace(' ','_',
|
819 |
$blog_name = preg_replace('/[^A-Za-z0-9_]/','', $blog_name);
|
820 |
if(!$blog_name) $blog_name = 'non_alpha_name';
|
821 |
|
@@ -973,13 +871,13 @@ class UpdraftPlus {
|
|
973 |
if (!$this->opened_log_time) $this->logfile_open($this->nonce);
|
974 |
|
975 |
// Get the blog name and rip out all non-alphanumeric chars other than _
|
976 |
-
$blog_name = preg_replace('/[^A-Za-z0-9_]/','', str_replace(' ','_',
|
977 |
if (!$blog_name) $blog_name = 'non_alpha_name';
|
978 |
$file_base = 'backup_'.date('Y-m-d-Hi',$this->backup_time).'_'.$blog_name.'_'.$this->nonce;
|
979 |
$backup_file_base = $updraft_dir.'/'.$file_base;
|
980 |
|
981 |
if ("finished" == $already_done) return basename($backup_file_base.'-db.gz');
|
982 |
-
if (
|
983 |
|
984 |
$total_tables = 0;
|
985 |
|
@@ -989,8 +887,8 @@ class UpdraftPlus {
|
|
989 |
$all_tables = array_map(create_function('$a', 'return $a[0];'), $all_tables);
|
990 |
|
991 |
if (!is_writable($updraft_dir)) {
|
992 |
-
$this->log(
|
993 |
-
$this->error(
|
994 |
return false;
|
995 |
}
|
996 |
|
@@ -999,7 +897,7 @@ class UpdraftPlus {
|
|
999 |
foreach ($all_tables as $table) {
|
1000 |
$total_tables++;
|
1001 |
// Increase script execution time-limit to 15 min for every table.
|
1002 |
-
if (
|
1003 |
// The table file may already exist if we have produced it on a previous run
|
1004 |
$table_file_prefix = $file_base.'-db-table-'.$table.'.table';
|
1005 |
if (file_exists($updraft_dir.'/'.$table_file_prefix.'.gz')) {
|
@@ -1027,26 +925,10 @@ class UpdraftPlus {
|
|
1027 |
$stitch_files[] = $table_file_prefix;
|
1028 |
}
|
1029 |
|
1030 |
-
// Race detection - with zip files now being resumable, these can more easily occur, with two running side-by-side
|
1031 |
-
$backup_final_file_name = $backup_file_base.'-db.gz';
|
1032 |
-
$time_now = time();
|
1033 |
-
$time_mod = (int)@filemtime($backup_final_file_name);
|
1034 |
-
if (file_exists($backup_final_file_name) && $time_mod>100 && ($time_now-$time_mod)<20) {
|
1035 |
-
$file_size = filesize($backup_final_file_name);
|
1036 |
-
$this->log("Terminate: the final database file ($backup_final_file_name) exists, and was modified within the last 20 seconds (time_mod=$time_mod, time_now=$time_now, diff=".($time_now-$time_mod).", size=$file_size). This likely means that another UpdraftPlus run is at work; so we will exit.");
|
1037 |
-
$this->increase_resume_and_reschedule(120);
|
1038 |
-
die;
|
1039 |
-
} elseif (file_exists($backup_final_file_name)) {
|
1040 |
-
$this->log("The final database file ($backup_final_file_name) exists, but was apparently not modified within the last 20 seconds (time_mod=$time_mod, time_now=$time_now, diff=".($time_now-$time_mod)."). Thus we assume that another UpdraftPlus terminated; thus we will continue.");
|
1041 |
-
}
|
1042 |
-
|
1043 |
// Finally, stitch the files together
|
1044 |
-
$this->backup_db_open($
|
1045 |
$this->backup_db_header();
|
1046 |
|
1047 |
-
// We delay the unlinking because if two runs go concurrently and fail to detect each other (should not happen, but there's no harm in assuming the detection failed) then that leads to files missing from the db dump
|
1048 |
-
$unlink_files = array();
|
1049 |
-
|
1050 |
foreach ($stitch_files as $table_file) {
|
1051 |
$this->log("{$table_file}.gz: adding to final database dump");
|
1052 |
if (!$handle = gzopen($updraft_dir.'/'.$table_file.'.gz', "r")) {
|
@@ -1055,7 +937,7 @@ class UpdraftPlus {
|
|
1055 |
} else {
|
1056 |
while ($line = gzgets($handle, 2048)) { $this->stow($line); }
|
1057 |
gzclose($handle);
|
1058 |
-
$
|
1059 |
}
|
1060 |
}
|
1061 |
|
@@ -1065,13 +947,9 @@ class UpdraftPlus {
|
|
1065 |
$this->stow("/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n");
|
1066 |
}
|
1067 |
|
1068 |
-
$this->log($file_base.'-db.gz: finished writing out complete database file
|
1069 |
$this->close($this->dbhandle);
|
1070 |
|
1071 |
-
foreach ($unlink_files as $unlink_file) {
|
1072 |
-
@unlink($unlink_file);
|
1073 |
-
}
|
1074 |
-
|
1075 |
if (count($this->errors)) {
|
1076 |
return false;
|
1077 |
} else {
|
@@ -1249,12 +1127,6 @@ class UpdraftPlus {
|
|
1249 |
|
1250 |
/*END OF WP-DB-BACKUP BLOCK */
|
1251 |
|
1252 |
-
function hourminute($pot) {
|
1253 |
-
if (preg_match("/^[0-2][0-9]:[0-5][0-9]$/", $pot)) return $pot;
|
1254 |
-
if ('' == $pot) return date('H:i', time()+300);
|
1255 |
-
return '00:00';
|
1256 |
-
}
|
1257 |
-
|
1258 |
/*
|
1259 |
this function is both the backup scheduler and ostensibly a filter callback for saving the option.
|
1260 |
it is called in the register_setting for the updraft_interval, which means when the admin settings
|
@@ -1272,8 +1144,7 @@ class UpdraftPlus {
|
|
1272 |
case 'weekly':
|
1273 |
case 'fortnightly':
|
1274 |
case 'monthly':
|
1275 |
-
|
1276 |
-
wp_schedule_event($first_time, $interval, 'updraft_backup');
|
1277 |
break;
|
1278 |
}
|
1279 |
return wp_filter_nohtml_kses($interval);
|
@@ -1299,8 +1170,7 @@ class UpdraftPlus {
|
|
1299 |
case 'weekly':
|
1300 |
case 'fortnightly':
|
1301 |
case 'monthly':
|
1302 |
-
|
1303 |
-
wp_schedule_event($first_time, $interval, 'updraft_backup_database');
|
1304 |
break;
|
1305 |
}
|
1306 |
return wp_filter_nohtml_kses($interval);
|
@@ -1317,7 +1187,7 @@ class UpdraftPlus {
|
|
1317 |
}
|
1318 |
|
1319 |
function backups_dir_location() {
|
1320 |
-
if (
|
1321 |
$updraft_dir = untrailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dir'));
|
1322 |
$default_backup_dir = WP_CONTENT_DIR.'/updraft';
|
1323 |
//if the option isn't set, default it to /backups inside the upload dir
|
@@ -1468,7 +1338,7 @@ class UpdraftPlus {
|
|
1468 |
}
|
1469 |
echo '</div>'; //close the updraft_restore_progress div
|
1470 |
# The 'off' check is for badly configured setups - http://wordpress.org/support/topic/plugin-wp-super-cache-warning-php-safe-mode-enabled-but-safe-mode-is-off
|
1471 |
-
if(
|
1472 |
echo "<p>DB could not be restored because PHP safe_mode is active on your server. You will need to manually restore the file via phpMyAdmin or another method.</p><br/>";
|
1473 |
return false;
|
1474 |
}
|
@@ -1583,6 +1453,11 @@ class UpdraftPlus {
|
|
1583 |
}
|
1584 |
}
|
1585 |
|
|
|
|
|
|
|
|
|
|
|
1586 |
function url_start($urls,$url) {
|
1587 |
return ($urls) ? '<a href="http://'.$url.'">' : "";
|
1588 |
}
|
@@ -1593,10 +1468,10 @@ class UpdraftPlus {
|
|
1593 |
|
1594 |
function wordshell_random_advert($urls) {
|
1595 |
if (defined('UPDRAFTPLUS_PREMIUM')) return "";
|
1596 |
-
$rad = rand(0,
|
1597 |
switch ($rad) {
|
1598 |
case 0:
|
1599 |
-
return
|
1600 |
break;
|
1601 |
case 1:
|
1602 |
return "Find UpdraftPlus useful? ".$this->url_start($urls,'david.dw-perspective.org.uk/donate')."Please make a donation.".$this->url_end($urls,'david.dw-perspective.org.uk/donate');
|
@@ -1611,7 +1486,7 @@ class UpdraftPlus {
|
|
1611 |
break;
|
1612 |
case 5:
|
1613 |
if (!defined('UPDRAFTPLUS_PREMIUM')) {
|
1614 |
-
return $this->url_start($urls,'updraftplus.com')."Need even more features and support? Check out UpdraftPlus Premium".$this->url_end($urls,'updraftplus.com');
|
1615 |
} else {
|
1616 |
return "Thanks for being an UpdraftPlus premium user. Keep visiting ".$this->url_start($urls,'www.updraftplus.com')."updraftplus.com".$this->url_end($urls,'www.updraftplus.com')." to see what's going on.";
|
1617 |
}
|
@@ -1619,12 +1494,6 @@ class UpdraftPlus {
|
|
1619 |
case 6:
|
1620 |
return "Need custom WordPress services from experts (including bespoke development)?".$this->url_start($urls,'www.simbahosting.co.uk/s3/products-and-services/wordpress-experts/')." Get them from the creators of UpdraftPlus.".$this->url_end($urls,'www.simbahosting.co.uk/s3/products-and-services/wordpress-experts/');
|
1621 |
break;
|
1622 |
-
case 7:
|
1623 |
-
return $this->url_start($urls,'www.updraftplus.com')."Check out UpdraftPlus.Com for help, add-ons and support".$this->url_end($urls,'www.updraftplus.com');
|
1624 |
-
break;
|
1625 |
-
case 8:
|
1626 |
-
return "Want to say thank-you for UpdraftPlus? ".$this->url_start($urls,'updraftplus.com/shop/')." Please buy our very cheap 'no adverts' add-on.".$this->url_end($urls,'updraftplus.com/shop/');
|
1627 |
-
break;
|
1628 |
}
|
1629 |
}
|
1630 |
|
@@ -1643,7 +1512,7 @@ class UpdraftPlus {
|
|
1643 |
echo ">$descrip</option>\n";
|
1644 |
}
|
1645 |
?>
|
1646 |
-
</select>
|
1647 |
and retain this many backups: <?php
|
1648 |
$updraft_retain = UpdraftPlus_Options::get_updraft_option('updraft_retain', 1);
|
1649 |
$updraft_retain = ((int)$updraft_retain > 0) ? (int)$updraft_retain : 1;
|
@@ -1660,7 +1529,7 @@ class UpdraftPlus {
|
|
1660 |
echo ">$descrip</option>\n";
|
1661 |
}
|
1662 |
?>
|
1663 |
-
</select>
|
1664 |
and retain this many backups: <?php
|
1665 |
$updraft_retain_db = UpdraftPlus_Options::get_updraft_option('updraft_retain_db', $updraft_retain);
|
1666 |
$updraft_retain_db = ((int)$updraft_retain_db > 0) ? (int)$updraft_retain_db : 1;
|
@@ -1668,9 +1537,7 @@ class UpdraftPlus {
|
|
1668 |
</td>
|
1669 |
</tr>
|
1670 |
<tr class="backup-interval-description">
|
1671 |
-
<td></td><td
|
1672 |
-
<?php echo apply_filters('updraftplus_fixtime_advert', '<p><strong>To fix the time at which a backup should take place, </strong> (e.g. if your server is busy at day and you want to run overnight), <a href="http://updraftplus.com/shop/fix-time/">use the "Fix Time" add-on</a></p>'); ?>
|
1673 |
-
</td>
|
1674 |
</tr>
|
1675 |
<?php
|
1676 |
# The true (default value if non-existent) here has the effect of forcing a default of on.
|
@@ -1686,7 +1553,7 @@ class UpdraftPlus {
|
|
1686 |
<input type="checkbox" name="updraft_include_plugins" value="1" <?php echo $include_plugins; ?> /> Plugins<br>
|
1687 |
<input type="checkbox" name="updraft_include_themes" value="1" <?php echo $include_themes; ?> /> Themes<br>
|
1688 |
<input type="checkbox" name="updraft_include_uploads" value="1" <?php echo $include_uploads; ?> /> Uploads<br>
|
1689 |
-
<input type="checkbox" name="updraft_include_others" value="1" <?php echo $include_others; ?> /> Any other directories found inside wp-content <?php if (is_multisite()) echo "(which on a multisite install includes users' blog contents) "; ?>- but exclude these directories: <input type="text" name="updraft_include_others_exclude" size="
|
1690 |
Include all of these, unless you are backing them up outside of UpdraftPlus. The above directories are usually everything (except for WordPress core itself which you can download afresh from WordPress.org). But if you have made customised modifications outside of these directories, you need to back them up another way. (<a href="http://wordshell.net">Use WordShell</a> for automatic backup, version control and patching).<br></td>
|
1691 |
</td>
|
1692 |
</tr>
|
@@ -1760,11 +1627,6 @@ class UpdraftPlus {
|
|
1760 |
});
|
1761 |
}
|
1762 |
jQuery(document).ready(function() {
|
1763 |
-
jQuery('#enableexpertmode').click(function() {
|
1764 |
-
jQuery('.expertmode').fadeIn();
|
1765 |
-
return false;
|
1766 |
-
});
|
1767 |
-
<?php if (!is_writable($updraft_dir)) echo "jQuery('.backupdirrow').show();\n"; ?>
|
1768 |
window.setTimeout(function(){updraft_showlastlog()}, 1200);
|
1769 |
jQuery('.updraftplusmethod').hide();
|
1770 |
<?php
|
@@ -1783,27 +1645,27 @@ class UpdraftPlus {
|
|
1783 |
<td colspan="2"><h2>Advanced / Debugging Settings</h2></td>
|
1784 |
</tr>
|
1785 |
<tr>
|
1786 |
-
<th>Debug mode:</th>
|
1787 |
-
<td><input type="checkbox" name="updraft_debug_mode" value="1" <?php echo $debug_mode; ?> /> <br>Check this to receive more information and emails on the backup process - useful if something is going wrong. You <strong>must</strong> send me this log if you are filing a bug report.</td>
|
1788 |
-
</tr>
|
1789 |
-
<tr>
|
1790 |
-
<th>Expert settings:</th>
|
1791 |
-
<td><a id="enableexpertmode" href="#">Show expert settings</a> - click this to show some further options; don't bother with this unless you have a problem or are curious.</td>
|
1792 |
</tr>
|
1793 |
<?php
|
1794 |
$delete_local = UpdraftPlus_Options::get_updraft_option('updraft_delete_local', 1);
|
1795 |
-
?>
|
1796 |
|
1797 |
-
<tr class="deletelocal
|
1798 |
<th>Delete local backup:</th>
|
1799 |
<td><input type="checkbox" name="updraft_delete_local" value="1" <?php if ($delete_local) echo 'checked="checked"'; ?>> <br>Uncheck this to prevent deletion of any superfluous backup files from your server after the backup run finishes (i.e. any files despatched remotely will also remain locally, and any files being kept locally will not be subject to the retention limits).</td>
|
1800 |
</tr>
|
1801 |
|
1802 |
-
|
|
|
|
|
|
|
|
|
1803 |
<th>Backup directory:</th>
|
1804 |
<td><input type="text" name="updraft_dir" style="width:525px" value="<?php echo htmlspecialchars($updraft_dir); ?>" /></td>
|
1805 |
</tr>
|
1806 |
-
<tr
|
1807 |
<td></td><td><?php
|
1808 |
|
1809 |
if(is_writable($updraft_dir)) {
|
@@ -1912,7 +1774,7 @@ class UpdraftPlus {
|
|
1912 |
if(isset($_POST['action']) && $_POST['action'] == 'updraft_backup_debug_all') { $this->boot_backup(true,true); }
|
1913 |
elseif (isset($_POST['action']) && $_POST['action'] == 'updraft_backup_debug_db') { $this->backup_db(); }
|
1914 |
elseif (isset($_POST['action']) && $_POST['action'] == 'updraft_wipesettings') {
|
1915 |
-
$settings = array('updraft_interval', 'updraft_interval_database', 'updraft_retain', 'updraft_retain_db', 'updraft_encryptionphrase', 'updraft_service', 'updraft_s3_login', 'updraft_s3_pass', 'updraft_s3_remote_path', 'updraft_dropbox_appkey', 'updraft_dropbox_secret', 'updraft_dropbox_folder', 'updraft_googledrive_clientid', 'updraft_googledrive_secret', 'updraft_googledrive_remotepath', 'updraft_ftp_login', 'updraft_ftp_pass', 'updraft_ftp_remote_path', 'updraft_server_address', 'updraft_dir', 'updraft_email', 'updraft_delete_local', 'updraft_debug_mode', 'updraft_include_plugins', 'updraft_include_themes', 'updraft_include_uploads', 'updraft_include_others', 'updraft_include_others_exclude', 'updraft_lastmessage', 'updraft_googledrive_clientid', 'updraft_googledrive_token', 'updraft_dropboxtk_request_token', 'updraft_dropboxtk_access_token', 'updraft_dropbox_folder', '
|
1916 |
foreach ($settings as $s) {
|
1917 |
UpdraftPlus_Options::delete_updraft_option($s);
|
1918 |
}
|
@@ -1923,7 +1785,7 @@ class UpdraftPlus {
|
|
1923 |
<div class="wrap">
|
1924 |
<h1><?php echo $this->plugin_title; ?></h1>
|
1925 |
|
1926 |
-
Maintained by <b>David Anderson</b> (<a href="http://
|
1927 |
<br>
|
1928 |
<?php
|
1929 |
if(isset($_GET['updraft_restore_success'])) {
|
@@ -1965,40 +1827,18 @@ class UpdraftPlus {
|
|
1965 |
<tr>
|
1966 |
<?php
|
1967 |
$updraft_dir = $this->backups_dir_location();
|
1968 |
-
// UNIX timestamp
|
1969 |
$next_scheduled_backup = wp_next_scheduled('updraft_backup');
|
1970 |
-
|
1971 |
-
// Convert to GMT
|
1972 |
-
$next_scheduled_backup_gmt = gmdate('Y-m-d H:i:s', $next_scheduled_backup);
|
1973 |
-
// Convert to blog time zone
|
1974 |
-
$next_scheduled_backup = get_date_from_gmt($next_scheduled_backup_gmt, 'D, F j, Y H:i T');
|
1975 |
-
} else {
|
1976 |
-
$next_scheduled_backup = 'No backups are scheduled at this time.';
|
1977 |
-
}
|
1978 |
-
|
1979 |
$next_scheduled_backup_database = wp_next_scheduled('updraft_backup_database');
|
1980 |
if (UpdraftPlus_Options::get_updraft_option('updraft_interval_database',UpdraftPlus_Options::get_updraft_option('updraft_interval')) == UpdraftPlus_Options::get_updraft_option('updraft_interval')) {
|
1981 |
$next_scheduled_backup_database = "Will take place at the same time as the files backup.";
|
1982 |
} else {
|
1983 |
-
|
1984 |
-
// Convert to GMT
|
1985 |
-
$next_scheduled_backup_database_gmt = gmdate('Y-m-d H:i:s', $next_scheduled_backup_database);
|
1986 |
-
// Convert to blog time zone
|
1987 |
-
$next_scheduled_backup_database = get_date_from_gmt($next_scheduled_backup_database_gmt, 'D, F j, Y H:i T');
|
1988 |
-
} else {
|
1989 |
-
$next_scheduled_backup_database = 'No backups are scheduled at this time.';
|
1990 |
-
}
|
1991 |
}
|
1992 |
-
$current_time =
|
1993 |
$updraft_last_backup = UpdraftPlus_Options::get_updraft_option('updraft_last_backup');
|
1994 |
if($updraft_last_backup) {
|
1995 |
-
|
1996 |
-
// Convert to GMT, then to blog time
|
1997 |
-
$last_backup = get_date_from_gmt(gmdate('Y-m-d H:i:s', $updraft_last_backup['backup_time']), 'D, F j, Y H:i T');
|
1998 |
-
} else {
|
1999 |
-
$last_backup = implode("<br>",$updraft_last_backup['errors']);
|
2000 |
-
}
|
2001 |
-
|
2002 |
$last_backup_color = ($updraft_last_backup['success']) ? 'green' : 'red';
|
2003 |
if (!empty($updraft_last_backup['backup_nonce'])) {
|
2004 |
$potential_log_file = $updraft_dir."/log.".$updraft_last_backup['backup_nonce'].".txt";
|
@@ -2035,7 +1875,7 @@ class UpdraftPlus {
|
|
2035 |
<div style="float:left; width:200px; padding-top: 40px;">
|
2036 |
<form method="post" action="">
|
2037 |
<input type="hidden" name="action" value="updraft_backup" />
|
2038 |
-
<p><input type="submit" <?php echo $backup_disabled ?> class="button-primary" value="Backup Now!" style="padding-top:
|
2039 |
</form>
|
2040 |
<div style="position:relative">
|
2041 |
<div style="position:absolute;top:0;left:0">
|
@@ -2044,7 +1884,7 @@ class UpdraftPlus {
|
|
2044 |
$backup_history = (is_array($backup_history))?$backup_history:array();
|
2045 |
$restore_disabled = (count($backup_history) == 0) ? 'disabled="disabled"' : "";
|
2046 |
?>
|
2047 |
-
<input type="button" class="button-primary" <?php echo $restore_disabled ?> value="Restore" style="padding-top:
|
2048 |
</div>
|
2049 |
<div style="display:none;position:absolute;top:0;left:0" id="backup-restore">
|
2050 |
<form method="post" action="">
|
@@ -2070,12 +1910,12 @@ class UpdraftPlus {
|
|
2070 |
<td id="updraft_lastlogcontainer"><?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_lastmessage', '(Nothing yet logged)')); ?></td>
|
2071 |
</tr>
|
2072 |
<tr>
|
2073 |
-
<th>Download backups
|
2074 |
<td><a href="#" title="Click to see available backups" onclick="jQuery('.download-backups').toggle();return false;"><?php echo count($backup_history)?> available</a></td>
|
2075 |
</tr>
|
2076 |
<tr>
|
2077 |
<td></td><td class="download-backups" style="display:none">
|
2078 |
-
<em>Click on a button to download the corresponding file to your computer. If you are using the <a href="http://opera.com">Opera web browser</a> then you should turn Turbo mode off
|
2079 |
<table>
|
2080 |
<?php
|
2081 |
foreach($backup_history as $key=>$value) {
|
@@ -2164,7 +2004,10 @@ class UpdraftPlus {
|
|
2164 |
<?php UpdraftPlus_Options::options_form_begin(); ?>
|
2165 |
<?php $this->settings_formcontents(); ?>
|
2166 |
</form>
|
2167 |
-
|
|
|
|
|
|
|
2168 |
<hr>
|
2169 |
<h3>Debug Information And Expert Options</h3>
|
2170 |
<p>
|
@@ -2193,6 +2036,7 @@ class UpdraftPlus {
|
|
2193 |
<p><input type="submit" class="button-primary" value="Wipe All Settings" onclick="return(confirm('This will delete all your UpdraftPlus settings - are you sure you want to do this?'))" /></p>
|
2194 |
</form>
|
2195 |
</div>
|
|
|
2196 |
|
2197 |
<script type="text/javascript">
|
2198 |
/* <![CDATA[ */
|
@@ -2224,194 +2068,11 @@ class UpdraftPlus {
|
|
2224 |
}
|
2225 |
|
2226 |
function show_admin_warning_dropbox() {
|
2227 |
-
$this->show_admin_warning('<strong>UpdraftPlus notice:</strong> <a href="
|
2228 |
}
|
2229 |
|
2230 |
function show_admin_warning_googledrive() {
|
2231 |
-
$this->show_admin_warning('<strong>UpdraftPlus notice:</strong> <a href="
|
2232 |
-
}
|
2233 |
-
|
2234 |
-
// Caution: $source is allowed to be an array, not just a filename
|
2235 |
-
function make_zipfile($source, $destination) {
|
2236 |
-
|
2237 |
-
// When to prefer PCL:
|
2238 |
-
// - We were asked to
|
2239 |
-
// - No zip extension present and no relevant method present
|
2240 |
-
// The zip extension check is not redundant, because method_exists segfaults some PHP installs, leading to support requests
|
2241 |
-
|
2242 |
-
// Fallback to PclZip - which my tests show is 25% slower
|
2243 |
-
if ($this->zip_preferpcl || (!extension_loaded('zip') && !method_exists('ZipArchive', 'AddFile'))) {
|
2244 |
-
if(!class_exists('PclZip')) require_once(ABSPATH.'/wp-admin/includes/class-pclzip.php');
|
2245 |
-
$zip_object = new PclZip($destination);
|
2246 |
-
$zipcode = $zip_object->create($source, PCLZIP_OPT_REMOVE_PATH, WP_CONTENT_DIR);
|
2247 |
-
if ($zipcode == 0 ) {
|
2248 |
-
$this->log("PclZip Error: ".$zip_object->errorName());
|
2249 |
-
return $zip_object->errorCode();
|
2250 |
-
} else {
|
2251 |
-
return true;
|
2252 |
-
}
|
2253 |
-
}
|
2254 |
-
|
2255 |
-
$this->existing_files = array();
|
2256 |
-
|
2257 |
-
// If the file exists, then we should grab its index of files inside, and sizes
|
2258 |
-
// Then, when we come to write a file, we should check if it's already there, and only add if it is not
|
2259 |
-
if (file_exists($destination) && is_readable($destination)) {
|
2260 |
-
$zip = new ZipArchive;
|
2261 |
-
$zip->open($destination);
|
2262 |
-
$this->log(basename($destination).": Zip file already exists, with ".$zip->numFiles." files");
|
2263 |
-
for ($i=0; $i<$zip->numFiles; $i++) {
|
2264 |
-
$si = $zip->statIndex($i);
|
2265 |
-
$name = $si['name'];
|
2266 |
-
$this->existing_files[$name] = $si['size'];
|
2267 |
-
}
|
2268 |
-
} elseif (file_exists($destination)) {
|
2269 |
-
$this->log("Zip file already exists, but is not readable; will remove: $destination");
|
2270 |
-
@unlink($destination);
|
2271 |
-
}
|
2272 |
-
|
2273 |
-
$this->zipfiles_added = 0;
|
2274 |
-
$this->zipfiles_dirbatched = array();
|
2275 |
-
$this->zipfiles_batched = array();
|
2276 |
-
|
2277 |
-
$last_error = -1;
|
2278 |
-
if (is_array($source)) {
|
2279 |
-
foreach ($source as $element) {
|
2280 |
-
$howmany = $this->makezip_recursive_add($destination, $element, basename($element), $element);
|
2281 |
-
if ($howmany < 0) {
|
2282 |
-
$last_error = $howmany;
|
2283 |
-
}
|
2284 |
-
}
|
2285 |
-
} else {
|
2286 |
-
$howmany = $this->makezip_recursive_add($destination, $source, basename($source), $source);
|
2287 |
-
if ($howmany < 0) {
|
2288 |
-
$last_error = $howmany;
|
2289 |
-
}
|
2290 |
-
}
|
2291 |
-
|
2292 |
-
// Any not yet dispatched?
|
2293 |
-
if (count($this->zipfiles_dirbatched)>0 || count($this->zipfiles_batched)>0) {
|
2294 |
-
$howmany = $this->makezip_addfiles($destination);
|
2295 |
-
if ($howmany < 0) {
|
2296 |
-
$last_error = $howmany;
|
2297 |
-
}
|
2298 |
-
}
|
2299 |
-
|
2300 |
-
if ($this->zipfiles_added > 0) {
|
2301 |
-
// ZipArchive::addFile sometimes fails
|
2302 |
-
if (filesize($destination) < 100) {
|
2303 |
-
// Retry with PclZip
|
2304 |
-
$this->log("Zip::addFile apparently failed - retrying with PclZip");
|
2305 |
-
$this->zip_preferpcl = true;
|
2306 |
-
return $this->make_zipfile($source, $destination);
|
2307 |
-
}
|
2308 |
-
return true;
|
2309 |
-
} else {
|
2310 |
-
return $last_error;
|
2311 |
-
}
|
2312 |
-
|
2313 |
-
}
|
2314 |
-
|
2315 |
-
// Q. Why don't we only open and close the zip file just once?
|
2316 |
-
// A. Because apparently PHP doesn't write out until the final close, and it will return an error if anything file has vanished in the meantime. So going directory-by-directory reduces our chances of hitting an error if the filesystem is changing underneath us (which is very possible if dealing with e.g. 1Gb of files)
|
2317 |
-
|
2318 |
-
// We batch up the files, rather than do them one at a time. So we are more efficient than open,one-write,close.
|
2319 |
-
function makezip_addfiles($zipfile) {
|
2320 |
-
$zip = new ZipArchive();
|
2321 |
-
if (file_exists($zipfile)) {
|
2322 |
-
$opencode = $zip->open($zipfile);
|
2323 |
-
} else {
|
2324 |
-
$opencode = $zip->open($zipfile, ZIPARCHIVE::CREATE);
|
2325 |
-
}
|
2326 |
-
if ($opencode !== true) return array($opencode, 0);
|
2327 |
-
// Make sure all directories are created before we start creating files
|
2328 |
-
while ($dir = array_pop($this->zipfiles_dirbatched)) {
|
2329 |
-
$zip->addEmptyDir($dir);
|
2330 |
-
}
|
2331 |
-
foreach ($this->zipfiles_batched as $file => $add_as) {
|
2332 |
-
if (!isset($this->existing_files[$add_as]) || $this->existing_files[$add_as] != filesize($file)) {
|
2333 |
-
$zip->addFile($file, $add_as);
|
2334 |
-
}
|
2335 |
-
$this->zipfiles_added++;
|
2336 |
-
if ($this->zipfiles_added % 100 == 0) $this->log("Zip: ".basename($zipfile).": ".$this->zipfiles_added." files added (size: ".round(filesize($zipfile)/1024,1)." Kb)");
|
2337 |
-
}
|
2338 |
-
// Reset the array
|
2339 |
-
$this->zipfiles_batched = array();
|
2340 |
-
return $zip->close();
|
2341 |
-
}
|
2342 |
-
|
2343 |
-
// This function recursively packs the zip, dereferencing symlinks but packing into a single-parent tree for universal unpacking
|
2344 |
-
function makezip_recursive_add($zipfile, $fullpath, $use_path_when_storing, $original_fullpath) {
|
2345 |
-
|
2346 |
-
// De-reference
|
2347 |
-
$fullpath = realpath($fullpath);
|
2348 |
-
|
2349 |
-
// Is the place we've ended up above the original base? That leads to infinite recursion
|
2350 |
-
if (($fullpath !== $original_fullpath && strpos($original_fullpath, $fullpath) === 0) || ($original_fullpath == $fullpath && strpos($use_path_when_storing, '/') !== false) ) {
|
2351 |
-
$this->log("Infinite recursion: symlink lead us to $fullpath, which is within $original_fullpath");
|
2352 |
-
$this->error("Infinite recursion: consult your log for more information");
|
2353 |
-
return false;
|
2354 |
-
}
|
2355 |
-
|
2356 |
-
if(is_file($fullpath)) {
|
2357 |
-
if (is_readable($fullpath)) {
|
2358 |
-
$key = $use_path_when_storing.'/'.basename($fullpath);
|
2359 |
-
$this->zipfiles_batched[$fullpath] = $use_path_when_storing.'/'.basename($fullpath);
|
2360 |
-
@touch($zipfile);
|
2361 |
-
} else {
|
2362 |
-
$this->log("$fullpath: unreadable file");
|
2363 |
-
$this->error("$fullpath: unreadable file");
|
2364 |
-
}
|
2365 |
-
} elseif (is_dir($fullpath)) {
|
2366 |
-
if (!isset($this->existing_files[$use_path_when_storing])) $this->zipfiles_dirbatched[] = $use_path_when_storing;
|
2367 |
-
if (!$dir_handle = @opendir($fullpath)) {
|
2368 |
-
$this->log("Failed to open directory: $fullpath");
|
2369 |
-
$this->error("Failed to open directory: $fullpath");
|
2370 |
-
return;
|
2371 |
-
}
|
2372 |
-
while ($e = readdir($dir_handle)) {
|
2373 |
-
if ($e != '.' && $e != '..') {
|
2374 |
-
if (is_link($fullpath.'/'.$e)) {
|
2375 |
-
$deref = realpath($fullpath.'/'.$e);
|
2376 |
-
if (is_file($deref)) {
|
2377 |
-
if (is_readable($deref)) {
|
2378 |
-
$this->zipfiles_batched[$deref] = $use_path_when_storing.'/'.$e;
|
2379 |
-
@touch($zipfile);
|
2380 |
-
} else {
|
2381 |
-
$this->log("$deref: unreadable file");
|
2382 |
-
$this->error("$deref: unreadable file");
|
2383 |
-
}
|
2384 |
-
} elseif (is_dir($deref)) {
|
2385 |
-
$this->makezip_recursive_add($zipfile, $deref, $use_path_when_storing.'/'.$e, $original_fullpath);
|
2386 |
-
}
|
2387 |
-
} elseif (is_file($fullpath.'/'.$e)) {
|
2388 |
-
if (is_readable($fullpath.'/'.$e)) {
|
2389 |
-
$this->zipfiles_batched[$fullpath.'/'.$e] = $use_path_when_storing.'/'.$e;
|
2390 |
-
@touch($zipfile);
|
2391 |
-
} else {
|
2392 |
-
$this->log("$fullpath/$e: unreadable file");
|
2393 |
-
$this->error("$fullpath/$e: unreadable file");
|
2394 |
-
}
|
2395 |
-
} elseif (is_dir($fullpath.'/'.$e)) {
|
2396 |
-
// no need to addEmptyDir here, as it gets done when we recurse
|
2397 |
-
$this->makezip_recursive_add($zipfile, $fullpath.'/'.$e, $use_path_when_storing.'/'.$e, $original_fullpath);
|
2398 |
-
}
|
2399 |
-
}
|
2400 |
-
}
|
2401 |
-
closedir($dir_handle);
|
2402 |
-
}
|
2403 |
-
|
2404 |
-
// We don't want to touch the zip file on every single file, so we batch them up
|
2405 |
-
// We go every 25 files, because if you wait too much longer, the contents may have changed from under you
|
2406 |
-
// And for some redundancy (redundant because of the touches going on anyway), we try to touch the file after 20 seconds, to help with the "recently modified" check on resumption (we saw a case where the file went for 155 seconds without being touched and so the other runner was not detected)
|
2407 |
-
if (count($this->zipfiles_batched) > 25 || (file_exists($zipfile) && ((time()-filemtime($zipfile)) > 20) )) {
|
2408 |
-
$ret = $this->makezip_addfiles($zipfile);
|
2409 |
-
} else {
|
2410 |
-
$ret = true;
|
2411 |
-
}
|
2412 |
-
|
2413 |
-
return $ret;
|
2414 |
-
|
2415 |
}
|
2416 |
|
2417 |
}
|
3 |
Plugin Name: UpdraftPlus - Backup/Restore
|
4 |
Plugin URI: http://wordpress.org/extend/plugins/updraftplus
|
5 |
Description: Backup and restore: your content and database can be automatically backed up to Amazon S3, Dropbox, Google Drive, FTP or email, on separate schedules.
|
6 |
+
Author: David Anderson.
|
7 |
+
Version: 1.3.14
|
8 |
Donate link: http://david.dw-perspective.org.uk/donate
|
9 |
License: GPLv3 or later
|
10 |
+
Author URI: http://wordshell.net
|
11 |
*/
|
12 |
|
13 |
/*
|
15 |
//Put in old-WP-version warning, and point them to where they can get help
|
16 |
//Add SFTP, Box.Net, SugarSync and Microsoft Skydrive support??
|
17 |
//The restorer has a hard-coded wp-content - fix
|
18 |
+
//Read safe-mode only once, remembering it will be totally removed from PHP
|
19 |
//Button for wiping files. Also auto-wipe on de-activate/de-install.
|
20 |
//Change DB encryption to not require whole gzip in memory (twice)
|
21 |
//improve error reporting / pretty up return messages in admin area. One thing: have a "backup is now finished" flag. Otherwise with the resuming things get ambiguous/confusing. See http://wordpress.org/support/topic/backup-status - user was not aware that backup completely failed. Maybe a "backup status" field for each nonce that gets updated? (Even via AJAX?)
|
23 |
//Should make clear in dashboard what is a non-fatal error (i.e. can be retried) - leads to unnecessary bug reports
|
24 |
// Move the inclusion, cloud and retention data into the backup job (i.e. don't read current config, make it an attribute of each job). In fact, everything should be. So audit all code for where get_option is called inside a backup run: it shouldn't happen.
|
25 |
// Should we resume if the only errors were upon deletion (i.e. the backup itself was fine?) Presently we do, but it displays errors for the user to confuse them. Perhaps better to make pruning a separate scheuled task??
|
26 |
+
// Make jobs *individually* resumable (i.e. all the state info must be keyed on the nonce; then call the resume event *specifying the nonce*)
|
27 |
// Warn the user if their zip-file creation is slooowww...
|
28 |
// Create a "Want Support?" button/console, that leads them through what is needed, and performs some basic tests...
|
29 |
// Resuming partial FTP uploads
|
30 |
+
// Turn expert options into a jQuery toggle
|
31 |
// Provide backup/restoration for UpdraftPlus's settings, to allow 'bootstrap' on a fresh WP install - some kind of single-use code which a remote UpdraftPlus can use to authenticate
|
32 |
// Multiple jobs
|
|
|
|
|
|
|
|
|
|
|
33 |
// When looking for files to delete, is the current encryption setting used? Should not be.
|
34 |
// Create single zip, containing even WordPress itself
|
|
|
35 |
// When a new backup starts, AJAX-update the 'Last backup' display in the admin page.
|
36 |
// Remove the recurrence of admin notices when settings are saved due to _wp_referer
|
|
|
|
|
|
|
37 |
|
38 |
Encrypt filesystem, if memory allows (and have option for abort if not); split up into multiple zips when needed
|
39 |
// Does not delete old custom directories upon a restore?
|
40 |
// Re-do making of zip files to allow resumption (every x files, store the state in a transient)
|
|
|
41 |
*/
|
42 |
|
43 |
/* Portions copyright 2010 Paul Kehrer
|
63 |
// 15 minutes
|
64 |
@set_time_limit(900);
|
65 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
if (!isset($updraftplus)) $updraftplus = new UpdraftPlus();
|
67 |
|
68 |
if (!$updraftplus->memory_check(192)) {
|
70 |
@ini_set('memory_limit', '192M'); //up the memory limit for large backup files
|
71 |
}
|
72 |
|
73 |
+
define('UPDRAFTPLUS_DIR', dirname(__FILE__));
|
74 |
+
define('UPDRAFTPLUS_URL', plugins_url('', __FILE__));
|
75 |
+
define('UPDRAFT_DEFAULT_OTHERS_EXCLUDE','upgrade,cache,updraft,index.php,backup');
|
76 |
+
|
77 |
+
if (is_file(UPDRAFTPLUS_DIR.'/premium.php')) require_once(UPDRAFTPLUS_DIR.'/premium.php');
|
78 |
+
|
79 |
if (!class_exists('UpdraftPlus_Options')) require_once(UPDRAFTPLUS_DIR.'/options.php');
|
80 |
|
81 |
class UpdraftPlus {
|
82 |
|
83 |
+
var $version = '1.3.14';
|
|
|
84 |
var $plugin_title = 'UpdraftPlus Backup/Restore';
|
85 |
|
86 |
// Choices will be shown in the admin menu in the order used here
|
105 |
|
106 |
var $jobdata;
|
107 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
108 |
function __construct() {
|
|
|
109 |
// Initialisation actions - takes place on plugin load
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
# Create admin page
|
111 |
add_action('admin_init', array($this, 'admin_init'));
|
112 |
add_action('updraft_backup', array($this,'backup_files'));
|
115 |
add_action('updraft_backup_all', array($this,'backup_all'));
|
116 |
# this is our runs-after-backup event, whose purpose is to see if it succeeded or failed, and resume/mom-up etc.
|
117 |
add_action('updraft_backup_resume', array($this,'backup_resume'), 10, 3);
|
118 |
+
add_action('wp_enqueue_scripts', array($this, 'ajax_enqueue') );
|
119 |
add_action('wp_ajax_updraft_download_backup', array($this, 'updraft_download_backup'));
|
120 |
add_action('wp_ajax_updraft_ajax', array($this, 'updraft_ajax_handler'));
|
121 |
# http://codex.wordpress.org/Plugin_API/Filter_Reference/cron_schedules
|
122 |
add_filter('cron_schedules', array($this,'modify_cron_schedules'));
|
123 |
add_filter('plugin_action_links', array($this, 'plugin_action_links'), 10, 2);
|
124 |
add_action('init', array($this, 'handle_url_actions'));
|
|
|
125 |
}
|
126 |
|
127 |
// Handle actions passed on to method plugins; e.g. Google OAuth 2.0 - ?page=updraftplus&action=updraftmethod-googledrive-auth
|
156 |
array_unshift($links, $settings_link);
|
157 |
$settings_link = '<a href="http://david.dw-perspective.org.uk/donate">'.__("Donate","UpdraftPlus").'</a>';
|
158 |
array_unshift($links, $settings_link);
|
|
|
|
|
159 |
}
|
160 |
return $links;
|
161 |
}
|
175 |
$this->opened_log_time = microtime(true);
|
176 |
$this->log("Opened log file at time: ".date('r'));
|
177 |
global $wp_version;
|
178 |
+
$this->log("UpdraftPlus: ".$this->version." WordPress: ".$wp_version." PHP: ".phpversion()." (".@php_uname().") PHP Max Execution Time: ".@ini_get("max_execution_time"));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
}
|
180 |
|
181 |
# Logs the given line, adding (relative) time stamp and newline
|
184 |
UpdraftPlus_Options::update_updraft_option("updraft_lastmessage", $line." (".date('M d H:i:s').")");
|
185 |
}
|
186 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
187 |
function backup_resume($resumption_no, $bnonce, $btime) {
|
188 |
|
189 |
@ignore_user_abort(true);
|
197 |
}
|
198 |
|
199 |
$this->log("Backup run: resumption=$resumption_no, nonce=$bnonce, begun at=$btime");
|
|
|
200 |
|
201 |
// Schedule again, to run in 5 minutes again, in case we again fail
|
202 |
+
$resume_delay = 300;
|
|
|
|
|
|
|
203 |
// A different argument than before is needed otherwise the event is ignored
|
204 |
$next_resumption = $resumption_no+1;
|
205 |
if ($next_resumption < 10) {
|
206 |
$this->log("Scheduling a resumption ($next_resumption) in case this run gets aborted");
|
207 |
+
wp_schedule_single_event(time()+$resume_delay, 'updraft_backup_resume', array($next_resumption, $bnonce, $btime));
|
|
|
|
|
208 |
} else {
|
209 |
+
$this->log("The current run is our tenth attempt - will not schedule a further attempt");
|
210 |
}
|
211 |
|
212 |
// This should be always called; if there were no files in this run, it returns us an empty array
|
228 |
$backup_database = $this->jobdata_get('backup_database');
|
229 |
|
230 |
// The transient is read and written below (instead of using the existing variable) so that we can copy-and-paste this part as needed.
|
231 |
+
if ($backup_database == "begun" || $backup_database == "finished" || $backup_database == "encrypted") {
|
232 |
if ($backup_database == "begun") {
|
233 |
if ($resumption_no > 0) {
|
234 |
$this->log("Resuming creation of database dump");
|
256 |
if (isset($our_files['db']) && !preg_match("/\.crypt$/", $our_files['db'])) {
|
257 |
$our_files['db'] = $this->encrypt_file($our_files['db']);
|
258 |
$this->save_backup_history($our_files);
|
259 |
+
$this->jobdata_set("backup_database", "encrypted");
|
260 |
}
|
261 |
|
262 |
foreach ($our_files as $key => $file) {
|
288 |
$this->cloud_backup($undone_files);
|
289 |
|
290 |
$this->log("Resume backup ($bnonce, $resumption_no): finish run");
|
|
|
291 |
$this->backup_finish($next_resumption, true, true, $resumption_no);
|
292 |
|
293 |
}
|
376 |
// Save what *should* be done, to make it resumable from this point on
|
377 |
if ($backup_database) $this->jobdata_set("backup_database", "begun");
|
378 |
if ($backup_files) $this->jobdata_set("backup_files", "begun");
|
|
|
|
|
|
|
|
|
379 |
|
380 |
// Everthing is now set up; now go
|
381 |
$this->backup_resume(0, $this->nonce, $this->backup_time);
|
438 |
if (empty($this->errors)) {
|
439 |
$send_an_email = true;
|
440 |
$final_message = "The backup apparently succeeded and is now complete";
|
441 |
+
} elseif ($resumption_no >=9) {
|
442 |
$send_an_email = true;
|
443 |
$final_message = "The backup attempt has finished, apparently unsuccesfully";
|
444 |
} else {
|
484 |
$backup_files = $this->jobdata_get("backup_files");
|
485 |
$backup_db = $this->jobdata_get("backup_database");
|
486 |
|
487 |
+
if ($backup_files == "finished" && ( $backup_db == "finished" || $backup_db == "encrypted" ) ) {
|
488 |
$backup_contains = "Files and database";
|
489 |
} elseif ($backup_files == "finished") {
|
490 |
$backup_contains = ($backup_db == "begun") ? "Files (database backup has not completed)" : "Files only (database was not part of this particular schedule)";
|
491 |
+
} elseif ($backup_db == "finished" || $backup_db == "encrypted") {
|
492 |
$backup_contains = ($backup_files == "begun") ? "Database (files backup has not completed)" : "Database only (files were not part of this particular schedule)";
|
493 |
} else {
|
494 |
$backup_contains = "Unknown/unexpected error - please raise a support request";
|
519 |
}
|
520 |
// Delete local files immediately if the option is set
|
521 |
// Where we are only backing up locally, only the "prune" function should do deleting
|
522 |
+
if (UpdraftPlus_Options::get_updraft_option('updraft_service', 'none') != 'none') $this->delete_local($file);
|
523 |
}
|
524 |
|
525 |
// Dispatch to the relevant function
|
526 |
function cloud_backup($backup_array) {
|
527 |
+
$service = UpdraftPlus_Options::get_updraft_option('updraft_service');
|
|
|
528 |
$this->log("Cloud backup selection: ".$service);
|
529 |
@set_time_limit(900);
|
530 |
|
547 |
}
|
548 |
}
|
549 |
|
550 |
+
function prune_file($updraft_service, $dofile, $method_object = null, $object_passback = null ) {
|
551 |
+
$this->log("Delete this file: $dofile, service=$updraft_service");
|
552 |
$fullpath = $this->backups_dir_location().'/'.$dofile;
|
553 |
// delete it if it's locally available
|
554 |
if (file_exists($fullpath)) {
|
561 |
}
|
562 |
|
563 |
// Carries out retain behaviour. Pass in a valid S3 or FTP object and path if relevant.
|
564 |
+
function prune_retained_backups($updraft_service, $backup_method_object = null, $backup_passback = null) {
|
565 |
|
566 |
// If they turned off deletion on local backups, then there is nothing to do
|
567 |
+
if (UpdraftPlus_Options::get_updraft_option('updraft_delete_local') == 0 && $updraft_service == 'none') {
|
568 |
$this->log("Prune old backups from local store: nothing to do, since the user disabled local deletion and we are using local backups");
|
569 |
return;
|
570 |
}
|
598 |
if ($db_backups_found > $updraft_retain_db) {
|
599 |
$this->log("$backup_datestamp: over retain limit ($updraft_retain_db); will delete this database");
|
600 |
$dofile = $backup_to_examine['db'];
|
601 |
+
if (!empty($dofile)) $this->prune_file($updraft_service, $dofile, $backup_method_object, $backup_passback);
|
602 |
unset($backup_to_examine['db']);
|
603 |
}
|
604 |
}
|
612 |
$file3 = isset($backup_to_examine['uploads']) ? $backup_to_examine['uploads'] : "";
|
613 |
$file4 = isset($backup_to_examine['others']) ? $backup_to_examine['others'] : "";
|
614 |
foreach (array($file, $file2, $file3, $file4) as $dofile) {
|
615 |
+
if (!empty($dofile)) $this->prune_file($updraft_service, $dofile, $backup_method_object, $backup_passback);
|
616 |
}
|
617 |
unset($backup_to_examine['plugins']);
|
618 |
unset($backup_to_examine['themes']);
|
654 |
return true;
|
655 |
}
|
656 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
657 |
function create_zip($create_from_dir, $whichone, $create_in_dir, $backup_file_basename) {
|
658 |
// Note: $create_from_dir can be an array or a string
|
659 |
@set_time_limit(900);
|
673 |
$zip_name = $full_path.'.tmp';
|
674 |
$time_now = time();
|
675 |
$time_mod = (int)@filemtime($zip_name);
|
676 |
+
if (file_exists($zip_name) && $time_mod>100 && ($time_now-$time_mod)<20) {
|
677 |
$file_size = filesize($zip_name);
|
678 |
+
$this->log("Terminate: the temporary file $zip_name already exists, and was modified within the last 20 seconds (time_mod=$time_mod, time_now=$time_now, diff=".($time_now-$time_mod).", size=$file_size). This likely means that another UpdraftPlus run is still at work; so we will exit.");
|
|
|
679 |
die;
|
|
|
|
|
680 |
}
|
681 |
|
682 |
+
$zip_object = new PclZip($zip_name);
|
683 |
+
|
684 |
$microtime_start = microtime(true);
|
685 |
# The paths in the zip should then begin with '$whichone', having removed WP_CONTENT_DIR from the front
|
686 |
+
if (!$zip_object->create($create_from_dir, PCLZIP_OPT_REMOVE_PATH, WP_CONTENT_DIR)) {
|
687 |
+
$this->log("ERROR: PclZip failure: Could not create $whichone zip");
|
688 |
+
$this->error("Could not create $whichone zip. Consult the log file for more information.");
|
|
|
689 |
return false;
|
690 |
} else {
|
691 |
rename($full_path.'.tmp', $full_path);
|
703 |
|
704 |
if(!$this->backup_time) $this->backup_time_nonce();
|
705 |
|
706 |
+
if(!class_exists('PclZip')) require_once(ABSPATH.'/wp-admin/includes/class-pclzip.php');
|
707 |
+
|
708 |
$updraft_dir = $this->backups_dir_location();
|
709 |
if(!is_writable($updraft_dir)) {
|
710 |
+
$this->log('Backup directory is not writable, or does not exist');
|
711 |
+
$this->error('Backup directory is not writable, or does not exist.');
|
712 |
return array();
|
713 |
}
|
714 |
|
715 |
//get the blog name and rip out all non-alphanumeric chars other than _
|
716 |
+
$blog_name = str_replace(' ','_',get_bloginfo());
|
717 |
$blog_name = preg_replace('/[^A-Za-z0-9_]/','', $blog_name);
|
718 |
if(!$blog_name) $blog_name = 'non_alpha_name';
|
719 |
|
871 |
if (!$this->opened_log_time) $this->logfile_open($this->nonce);
|
872 |
|
873 |
// Get the blog name and rip out all non-alphanumeric chars other than _
|
874 |
+
$blog_name = preg_replace('/[^A-Za-z0-9_]/','', str_replace(' ','_', get_bloginfo()));
|
875 |
if (!$blog_name) $blog_name = 'non_alpha_name';
|
876 |
$file_base = 'backup_'.date('Y-m-d-Hi',$this->backup_time).'_'.$blog_name.'_'.$this->nonce;
|
877 |
$backup_file_base = $updraft_dir.'/'.$file_base;
|
878 |
|
879 |
if ("finished" == $already_done) return basename($backup_file_base.'-db.gz');
|
880 |
+
if ("encrypted" == $already_done) return basename($backup_file_base.'-db.gz.crypt');
|
881 |
|
882 |
$total_tables = 0;
|
883 |
|
887 |
$all_tables = array_map(create_function('$a', 'return $a[0];'), $all_tables);
|
888 |
|
889 |
if (!is_writable($updraft_dir)) {
|
890 |
+
$this->log('The backup directory is not writable.');
|
891 |
+
$this->error('The backup directory is not writable.');
|
892 |
return false;
|
893 |
}
|
894 |
|
897 |
foreach ($all_tables as $table) {
|
898 |
$total_tables++;
|
899 |
// Increase script execution time-limit to 15 min for every table.
|
900 |
+
if ( !ini_get('safe_mode') || strtolower(ini_get('safe_mode')) == "off") @set_time_limit(15*60);
|
901 |
// The table file may already exist if we have produced it on a previous run
|
902 |
$table_file_prefix = $file_base.'-db-table-'.$table.'.table';
|
903 |
if (file_exists($updraft_dir.'/'.$table_file_prefix.'.gz')) {
|
925 |
$stitch_files[] = $table_file_prefix;
|
926 |
}
|
927 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
928 |
// Finally, stitch the files together
|
929 |
+
$this->backup_db_open($backup_file_base.'-db.gz', true);
|
930 |
$this->backup_db_header();
|
931 |
|
|
|
|
|
|
|
932 |
foreach ($stitch_files as $table_file) {
|
933 |
$this->log("{$table_file}.gz: adding to final database dump");
|
934 |
if (!$handle = gzopen($updraft_dir.'/'.$table_file.'.gz', "r")) {
|
937 |
} else {
|
938 |
while ($line = gzgets($handle, 2048)) { $this->stow($line); }
|
939 |
gzclose($handle);
|
940 |
+
@unlink($updraft_dir.'/'.$table_file.'.gz');
|
941 |
}
|
942 |
}
|
943 |
|
947 |
$this->stow("/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n");
|
948 |
}
|
949 |
|
950 |
+
$this->log($file_base.'-db.gz: finished writing out complete database file');
|
951 |
$this->close($this->dbhandle);
|
952 |
|
|
|
|
|
|
|
|
|
953 |
if (count($this->errors)) {
|
954 |
return false;
|
955 |
} else {
|
1127 |
|
1128 |
/*END OF WP-DB-BACKUP BLOCK */
|
1129 |
|
|
|
|
|
|
|
|
|
|
|
|
|
1130 |
/*
|
1131 |
this function is both the backup scheduler and ostensibly a filter callback for saving the option.
|
1132 |
it is called in the register_setting for the updraft_interval, which means when the admin settings
|
1144 |
case 'weekly':
|
1145 |
case 'fortnightly':
|
1146 |
case 'monthly':
|
1147 |
+
wp_schedule_event(time()+30, $interval, 'updraft_backup');
|
|
|
1148 |
break;
|
1149 |
}
|
1150 |
return wp_filter_nohtml_kses($interval);
|
1170 |
case 'weekly':
|
1171 |
case 'fortnightly':
|
1172 |
case 'monthly':
|
1173 |
+
wp_schedule_event(time()+30, $interval, 'updraft_backup_database');
|
|
|
1174 |
break;
|
1175 |
}
|
1176 |
return wp_filter_nohtml_kses($interval);
|
1187 |
}
|
1188 |
|
1189 |
function backups_dir_location() {
|
1190 |
+
if (isset($this->backup_dir)) return $this->backup_dir;
|
1191 |
$updraft_dir = untrailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dir'));
|
1192 |
$default_backup_dir = WP_CONTENT_DIR.'/updraft';
|
1193 |
//if the option isn't set, default it to /backups inside the upload dir
|
1338 |
}
|
1339 |
echo '</div>'; //close the updraft_restore_progress div
|
1340 |
# The 'off' check is for badly configured setups - http://wordpress.org/support/topic/plugin-wp-super-cache-warning-php-safe-mode-enabled-but-safe-mode-is-off
|
1341 |
+
if(ini_get('safe_mode') && strtolower(ini_get('safe_mode')) != "off") {
|
1342 |
echo "<p>DB could not be restored because PHP safe_mode is active on your server. You will need to manually restore the file via phpMyAdmin or another method.</p><br/>";
|
1343 |
return false;
|
1344 |
}
|
1453 |
}
|
1454 |
}
|
1455 |
|
1456 |
+
function ajax_enqueue() {
|
1457 |
+
// wp_enqueue_script('updraftplus-ajax', plugins_url('/includes/ajax.js', __FILE__) );
|
1458 |
+
// wp_localize_script('updraftplus-ajax', 'updraft_credentials_test', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
|
1459 |
+
}
|
1460 |
+
|
1461 |
function url_start($urls,$url) {
|
1462 |
return ($urls) ? '<a href="http://'.$url.'">' : "";
|
1463 |
}
|
1468 |
|
1469 |
function wordshell_random_advert($urls) {
|
1470 |
if (defined('UPDRAFTPLUS_PREMIUM')) return "";
|
1471 |
+
$rad = rand(0,6);
|
1472 |
switch ($rad) {
|
1473 |
case 0:
|
1474 |
+
return "Like automating WordPress operations? Use the CLI? ".$this->url_start($urls,'wordshell.net')."You will love WordShell".$this->url_end($urls,'www.wordshell.net')." - saves time and money fast.";
|
1475 |
break;
|
1476 |
case 1:
|
1477 |
return "Find UpdraftPlus useful? ".$this->url_start($urls,'david.dw-perspective.org.uk/donate')."Please make a donation.".$this->url_end($urls,'david.dw-perspective.org.uk/donate');
|
1486 |
break;
|
1487 |
case 5:
|
1488 |
if (!defined('UPDRAFTPLUS_PREMIUM')) {
|
1489 |
+
return $this->url_start($urls,'www.updraftplus.com')."Need even more features and support? Check out UpdraftPlus Premium".$this->url_end($urls,'www.updraftplus.com');
|
1490 |
} else {
|
1491 |
return "Thanks for being an UpdraftPlus premium user. Keep visiting ".$this->url_start($urls,'www.updraftplus.com')."updraftplus.com".$this->url_end($urls,'www.updraftplus.com')." to see what's going on.";
|
1492 |
}
|
1494 |
case 6:
|
1495 |
return "Need custom WordPress services from experts (including bespoke development)?".$this->url_start($urls,'www.simbahosting.co.uk/s3/products-and-services/wordpress-experts/')." Get them from the creators of UpdraftPlus.".$this->url_end($urls,'www.simbahosting.co.uk/s3/products-and-services/wordpress-experts/');
|
1496 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
1497 |
}
|
1498 |
}
|
1499 |
|
1512 |
echo ">$descrip</option>\n";
|
1513 |
}
|
1514 |
?>
|
1515 |
+
</select>
|
1516 |
and retain this many backups: <?php
|
1517 |
$updraft_retain = UpdraftPlus_Options::get_updraft_option('updraft_retain', 1);
|
1518 |
$updraft_retain = ((int)$updraft_retain > 0) ? (int)$updraft_retain : 1;
|
1529 |
echo ">$descrip</option>\n";
|
1530 |
}
|
1531 |
?>
|
1532 |
+
</select>
|
1533 |
and retain this many backups: <?php
|
1534 |
$updraft_retain_db = UpdraftPlus_Options::get_updraft_option('updraft_retain_db', $updraft_retain);
|
1535 |
$updraft_retain_db = ((int)$updraft_retain_db > 0) ? (int)$updraft_retain_db : 1;
|
1537 |
</td>
|
1538 |
</tr>
|
1539 |
<tr class="backup-interval-description">
|
1540 |
+
<td></td><td>If you would like to automatically schedule backups, choose schedules from the dropdowns above. Backups will occur at the intervals specified starting just after the current time. If the two schedules are the same, then the two backups will take place together. If you choose "manual" then you must click the "Backup Now!" button whenever you wish a backup to occur. </td>
|
|
|
|
|
1541 |
</tr>
|
1542 |
<?php
|
1543 |
# The true (default value if non-existent) here has the effect of forcing a default of on.
|
1553 |
<input type="checkbox" name="updraft_include_plugins" value="1" <?php echo $include_plugins; ?> /> Plugins<br>
|
1554 |
<input type="checkbox" name="updraft_include_themes" value="1" <?php echo $include_themes; ?> /> Themes<br>
|
1555 |
<input type="checkbox" name="updraft_include_uploads" value="1" <?php echo $include_uploads; ?> /> Uploads<br>
|
1556 |
+
<input type="checkbox" name="updraft_include_others" value="1" <?php echo $include_others; ?> /> Any other directories found inside wp-content <?php if (is_multisite()) echo "(which on a multisite install includes users' blog contents) "; ?>- but exclude these directories: <input type="text" name="updraft_include_others_exclude" size="32" value="<?php echo htmlspecialchars($include_others_exclude); ?>"/><br>
|
1557 |
Include all of these, unless you are backing them up outside of UpdraftPlus. The above directories are usually everything (except for WordPress core itself which you can download afresh from WordPress.org). But if you have made customised modifications outside of these directories, you need to back them up another way. (<a href="http://wordshell.net">Use WordShell</a> for automatic backup, version control and patching).<br></td>
|
1558 |
</td>
|
1559 |
</tr>
|
1627 |
});
|
1628 |
}
|
1629 |
jQuery(document).ready(function() {
|
|
|
|
|
|
|
|
|
|
|
1630 |
window.setTimeout(function(){updraft_showlastlog()}, 1200);
|
1631 |
jQuery('.updraftplusmethod').hide();
|
1632 |
<?php
|
1645 |
<td colspan="2"><h2>Advanced / Debugging Settings</h2></td>
|
1646 |
</tr>
|
1647 |
<tr>
|
1648 |
+
<th>Debug / Expert mode:</th>
|
1649 |
+
<td><input type="checkbox" name="updraft_debug_mode" value="1" <?php echo $debug_mode; ?> /> <br>Check this to enable some more options here and below (that will appear after you save), and potentially receive more information and emails on the backup process - useful if something is going wrong. You <strong>must</strong> send me this log if you are filing a bug report.</td>
|
|
|
|
|
|
|
|
|
1650 |
</tr>
|
1651 |
<?php
|
1652 |
$delete_local = UpdraftPlus_Options::get_updraft_option('updraft_delete_local', 1);
|
1653 |
+
if (UpdraftPlus_Options::get_updraft_option('updraft_debug_mode')) { ?>
|
1654 |
|
1655 |
+
<tr class="deletelocal">
|
1656 |
<th>Delete local backup:</th>
|
1657 |
<td><input type="checkbox" name="updraft_delete_local" value="1" <?php if ($delete_local) echo 'checked="checked"'; ?>> <br>Uncheck this to prevent deletion of any superfluous backup files from your server after the backup run finishes (i.e. any files despatched remotely will also remain locally, and any files being kept locally will not be subject to the retention limits).</td>
|
1658 |
</tr>
|
1659 |
|
1660 |
+
<?php } else { ?>
|
1661 |
+
<input type="hidden" name="updraft_delete_local" value="<?php echo ($delete_local) ? 1 : 0; ?>">
|
1662 |
+
<?php } ?>
|
1663 |
+
|
1664 |
+
<tr>
|
1665 |
<th>Backup directory:</th>
|
1666 |
<td><input type="text" name="updraft_dir" style="width:525px" value="<?php echo htmlspecialchars($updraft_dir); ?>" /></td>
|
1667 |
</tr>
|
1668 |
+
<tr>
|
1669 |
<td></td><td><?php
|
1670 |
|
1671 |
if(is_writable($updraft_dir)) {
|
1774 |
if(isset($_POST['action']) && $_POST['action'] == 'updraft_backup_debug_all') { $this->boot_backup(true,true); }
|
1775 |
elseif (isset($_POST['action']) && $_POST['action'] == 'updraft_backup_debug_db') { $this->backup_db(); }
|
1776 |
elseif (isset($_POST['action']) && $_POST['action'] == 'updraft_wipesettings') {
|
1777 |
+
$settings = array('updraft_interval', 'updraft_interval_database', 'updraft_retain', 'updraft_retain_db', 'updraft_encryptionphrase', 'updraft_service', 'updraft_s3_login', 'updraft_s3_pass', 'updraft_s3_remote_path', 'updraft_dropbox_appkey', 'updraft_dropbox_secret', 'updraft_dropbox_folder', 'updraft_googledrive_clientid', 'updraft_googledrive_secret', 'updraft_googledrive_remotepath', 'updraft_ftp_login', 'updraft_ftp_pass', 'updraft_ftp_remote_path', 'updraft_server_address', 'updraft_dir', 'updraft_email', 'updraft_delete_local', 'updraft_debug_mode', 'updraft_include_plugins', 'updraft_include_themes', 'updraft_include_uploads', 'updraft_include_others', 'updraft_include_others_exclude', 'updraft_lastmessage', 'updraft_googledrive_clientid', 'updraft_googledrive_token', 'updraft_dropboxtk_request_token', 'updraft_dropboxtk_access_token', 'updraft_dropbox_folder', '');
|
1778 |
foreach ($settings as $s) {
|
1779 |
UpdraftPlus_Options::delete_updraft_option($s);
|
1780 |
}
|
1785 |
<div class="wrap">
|
1786 |
<h1><?php echo $this->plugin_title; ?></h1>
|
1787 |
|
1788 |
+
Maintained by <b>David Anderson</b> (<a href="http://david.dw-perspective.org.uk">Homepage</a><?php if (!defined('UPDRAFTPLUS_PREMIUM')) { ?> | <a href="http://updraftplus.com">Premium</a> | <a href="http://wordshell.net">WordShell - WordPress command line</a> | <a href="http://david.dw-perspective.org.uk/donate">Donate</a><?php } ?> | <a href="http://wordpress.org/extend/plugins/updraftplus/faq/">FAQs</a> | <a href="http://profiles.wordpress.org/davidanderson/">My other WordPress plugins</a>). Version: <?php echo $this->version; ?>
|
1789 |
<br>
|
1790 |
<?php
|
1791 |
if(isset($_GET['updraft_restore_success'])) {
|
1827 |
<tr>
|
1828 |
<?php
|
1829 |
$updraft_dir = $this->backups_dir_location();
|
|
|
1830 |
$next_scheduled_backup = wp_next_scheduled('updraft_backup');
|
1831 |
+
$next_scheduled_backup = ($next_scheduled_backup) ? date('D, F j, Y H:i T',$next_scheduled_backup) : 'No backups are scheduled at this time.';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1832 |
$next_scheduled_backup_database = wp_next_scheduled('updraft_backup_database');
|
1833 |
if (UpdraftPlus_Options::get_updraft_option('updraft_interval_database',UpdraftPlus_Options::get_updraft_option('updraft_interval')) == UpdraftPlus_Options::get_updraft_option('updraft_interval')) {
|
1834 |
$next_scheduled_backup_database = "Will take place at the same time as the files backup.";
|
1835 |
} else {
|
1836 |
+
$next_scheduled_backup_database = ($next_scheduled_backup_database) ? date('D, F j, Y H:i T',$next_scheduled_backup_database) : 'No backups are scheduled at this time.';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1837 |
}
|
1838 |
+
$current_time = date('D, F j, Y H:i T',time());
|
1839 |
$updraft_last_backup = UpdraftPlus_Options::get_updraft_option('updraft_last_backup');
|
1840 |
if($updraft_last_backup) {
|
1841 |
+
$last_backup = ($updraft_last_backup['success']) ? date('D, F j, Y H:i T',$updraft_last_backup['backup_time']) : implode("<br>",$updraft_last_backup['errors']);
|
|
|
|
|
|
|
|
|
|
|
|
|
1842 |
$last_backup_color = ($updraft_last_backup['success']) ? 'green' : 'red';
|
1843 |
if (!empty($updraft_last_backup['backup_nonce'])) {
|
1844 |
$potential_log_file = $updraft_dir."/log.".$updraft_last_backup['backup_nonce'].".txt";
|
1875 |
<div style="float:left; width:200px; padding-top: 40px;">
|
1876 |
<form method="post" action="">
|
1877 |
<input type="hidden" name="action" value="updraft_backup" />
|
1878 |
+
<p><input type="submit" <?php echo $backup_disabled ?> class="button-primary" value="Backup Now!" style="padding-top:3px;padding-bottom:3px;font-size:24px !important" onclick="return(confirm('This will schedule a one-time backup. To trigger the backup you should go ahead, then wait 10 seconds, then visit any page on your site. WordPress should then start the backup running in the background.'))"></p>
|
1879 |
</form>
|
1880 |
<div style="position:relative">
|
1881 |
<div style="position:absolute;top:0;left:0">
|
1884 |
$backup_history = (is_array($backup_history))?$backup_history:array();
|
1885 |
$restore_disabled = (count($backup_history) == 0) ? 'disabled="disabled"' : "";
|
1886 |
?>
|
1887 |
+
<input type="button" class="button-primary" <?php echo $restore_disabled ?> value="Restore" style="padding-top:3px;padding-bottom:3px;font-size:24px !important" onclick="jQuery('#backup-restore').fadeIn('slow');jQuery(this).parent().fadeOut('slow')">
|
1888 |
</div>
|
1889 |
<div style="display:none;position:absolute;top:0;left:0" id="backup-restore">
|
1890 |
<form method="post" action="">
|
1910 |
<td id="updraft_lastlogcontainer"><?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_lastmessage', '(Nothing yet logged)')); ?></td>
|
1911 |
</tr>
|
1912 |
<tr>
|
1913 |
+
<th>Download backups</th>
|
1914 |
<td><a href="#" title="Click to see available backups" onclick="jQuery('.download-backups').toggle();return false;"><?php echo count($backup_history)?> available</a></td>
|
1915 |
</tr>
|
1916 |
<tr>
|
1917 |
<td></td><td class="download-backups" style="display:none">
|
1918 |
+
<em>Click on a button to download the corresponding file to your computer. If you are using the <a href="http://opera.com">Opera web browser</a> then you should turn Turbo mode off.</em>
|
1919 |
<table>
|
1920 |
<?php
|
1921 |
foreach($backup_history as $key=>$value) {
|
2004 |
<?php UpdraftPlus_Options::options_form_begin(); ?>
|
2005 |
<?php $this->settings_formcontents(); ?>
|
2006 |
</form>
|
2007 |
+
<?php
|
2008 |
+
if (UpdraftPlus_Options::get_updraft_option('updraft_debug_mode')) {
|
2009 |
+
?>
|
2010 |
+
<div style="padding-top: 40px;">
|
2011 |
<hr>
|
2012 |
<h3>Debug Information And Expert Options</h3>
|
2013 |
<p>
|
2036 |
<p><input type="submit" class="button-primary" value="Wipe All Settings" onclick="return(confirm('This will delete all your UpdraftPlus settings - are you sure you want to do this?'))" /></p>
|
2037 |
</form>
|
2038 |
</div>
|
2039 |
+
<?php } ?>
|
2040 |
|
2041 |
<script type="text/javascript">
|
2042 |
/* <![CDATA[ */
|
2068 |
}
|
2069 |
|
2070 |
function show_admin_warning_dropbox() {
|
2071 |
+
$this->show_admin_warning('<strong>UpdraftPlus notice:</strong> <a href="?page=updraftplus&action=updraftmethod-dropbox-auth&updraftplus_dropboxauth=doit">Click here to authenticate your Dropbox account (you will not be able to back up to Dropbox without it).</a>');
|
2072 |
}
|
2073 |
|
2074 |
function show_admin_warning_googledrive() {
|
2075 |
+
$this->show_admin_warning('<strong>UpdraftPlus notice:</strong> <a href="?page=updraftplus&action=updraftmethod-googledrive-auth&updraftplus_googleauth=doit">Click here to authenticate your Google Drive account (you will not be able to back up to Google Drive without it).</a>');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2076 |
}
|
2077 |
|
2078 |
}
|