├── .gitignore
├── README
├── config
└── googleplus.php
├── libraries
└── Googleplus.php
└── third_party
└── google-api-php-client
├── LICENSE
├── NOTICE
├── README
└── src
├── Google_Client.php
├── auth
├── Google_AssertionCredentials.php
├── Google_Auth.php
├── Google_AuthNone.php
├── Google_LoginTicket.php
├── Google_OAuth2.php
├── Google_P12Signer.php
├── Google_PemVerifier.php
├── Google_Signer.php
└── Google_Verifier.php
├── cache
├── Google_ApcCache.php
├── Google_Cache.php
├── Google_FileCache.php
└── Google_MemcacheCache.php
├── config.php
├── contrib
└── Google_PlusService.php
├── external
├── OAuth.php
└── URITemplateParser.php
├── io
├── Google_CacheParser.php
├── Google_CurlIO.php
├── Google_HttpRequest.php
├── Google_IO.php
├── Google_REST.php
└── cacerts.pem
└── service
├── Google_BatchRequest.php
├── Google_MediaFileUpload.php
├── Google_Model.php
├── Google_Service.php
├── Google_ServiceResource.php
└── Google_Utils.php
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | Just upload these files into your CodeIgniter application folder and set the config variables. You can then load the library like this
2 | $this->load->library('googleplus');
3 |
4 | Example usage:
5 | $this->googleplus->people->get('me'); // when authorized
6 | $this->googleplus->people->get('115414977082318263605'); // that's me :-)
7 |
8 | Read the full API docs on the Google+ website http://developers.google.com/+/api
9 |
10 | Uses the Google APIs Client Library for PHP
11 | http://code.google.com/p/google-api-php-client/
--------------------------------------------------------------------------------
/config/googleplus.php:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/libraries/Googleplus.php:
--------------------------------------------------------------------------------
1 | config->load('googleplus');
9 |
10 | require APPPATH .'third_party/google-api-php-client/src/Google_Client.php';
11 | require APPPATH .'third_party/google-api-php-client/src/contrib/Google_PlusService.php';
12 |
13 | $cache_path = $CI->config->item('cache_path');
14 | $GLOBALS['apiConfig']['ioFileCache_directory'] = ($cache_path == '') ? APPPATH .'cache/' : $cache_path;
15 |
16 | $this->client = new Google_Client();
17 | $this->client->setApplicationName($CI->config->item('application_name', 'googleplus'));
18 | $this->client->setClientId($CI->config->item('client_id', 'googleplus'));
19 | $this->client->setClientSecret($CI->config->item('client_secret', 'googleplus'));
20 | $this->client->setRedirectUri($CI->config->item('redirect_uri', 'googleplus'));
21 | $this->client->setDeveloperKey($CI->config->item('api_key', 'googleplus'));
22 |
23 | $this->plus = new Google_PlusService($this->client);
24 |
25 | }
26 |
27 | public function __get($name) {
28 |
29 | if(isset($this->plus->$name)) {
30 | return $this->plus->$name;
31 | }
32 | return false;
33 |
34 | }
35 |
36 | public function __call($name, $arguments) {
37 |
38 | if(method_exists($this->plus, $name)) {
39 | return call_user_func(array($this->plus, $name), $arguments);
40 | }
41 | return false;
42 |
43 | }
44 |
45 | }
46 | ?>
--------------------------------------------------------------------------------
/third_party/google-api-php-client/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
203 |
204 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/NOTICE:
--------------------------------------------------------------------------------
1 | This product contains the following libraries:
2 |
3 | XRDS-Simple library from http://code.google.com/p/diso/
4 | Apache License 2.0
5 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/README:
--------------------------------------------------------------------------------
1 | Google APIs Client Library for PHP
2 | =====================================
3 |
4 | == Description
5 | The Google API Client Library enables you to work with Google APIs such as Google+, Drive, Tasks, or Latitude on your server.
6 |
7 | Requirements:
8 | PHP 5.2.x or higher [http://www.php.net/]
9 | PHP Curl extension [http://www.php.net/manual/en/intro.curl.php]
10 | PHP JSON extension [http://php.net/manual/en/book.json.php]
11 |
12 | Project page:
13 | http://code.google.com/p/google-api-php-client
14 |
15 | OAuth 2 instructions:
16 | http://code.google.com/p/google-api-php-client/wiki/OAuth2
17 |
18 | Report a defect or feature request here:
19 | http://code.google.com/p/google-api-php-client/issues/entry
20 |
21 | Subscribe to project updates in your feed reader:
22 | http://code.google.com/feeds/p/google-api-php-client/updates/basic
23 |
24 | Supported sample applications:
25 | http://code.google.com/p/google-api-php-client/wiki/Samples
26 |
27 | == Basic Example
28 | 'free-ebooks');
36 | $results = $service->volumes->listVolumes('Henry David Thoreau', $optParams);
37 |
38 | foreach ($results['items'] as $item) {
39 | print($item['volumeInfo']['title'] . '
');
40 | }
41 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/Google_Client.php:
--------------------------------------------------------------------------------
1 |
66 | * @author Chirag Shah
67 | */
68 | class Google_Client {
69 | /**
70 | * @static
71 | * @var Google_Auth $auth
72 | */
73 | static $auth;
74 |
75 | /**
76 | * @static
77 | * @var Google_IO $io
78 | */
79 | static $io;
80 |
81 | /**
82 | * @static
83 | * @var Google_Cache $cache
84 | */
85 | static $cache;
86 |
87 | /**
88 | * @static
89 | * @var boolean $useBatch
90 | */
91 | static $useBatch = false;
92 |
93 | /** @var array $scopes */
94 | protected $scopes = array();
95 |
96 | /** @var bool $useObjects */
97 | protected $useObjects = false;
98 |
99 | // definitions of services that are discovered.
100 | protected $services = array();
101 |
102 | // Used to track authenticated state, can't discover services after doing authenticate()
103 | private $authenticated = false;
104 |
105 | public function __construct($config = array()) {
106 | global $apiConfig;
107 | $apiConfig = array_merge($apiConfig, $config);
108 | self::$cache = new $apiConfig['cacheClass']();
109 | self::$auth = new $apiConfig['authClass']();
110 | self::$io = new $apiConfig['ioClass']();
111 | }
112 |
113 | /**
114 | * Add a service
115 | */
116 | public function addService($service, $version = false) {
117 | global $apiConfig;
118 | if ($this->authenticated) {
119 | throw new Google_Exception('Cant add services after having authenticated');
120 | }
121 | $this->services[$service] = array();
122 | if (isset($apiConfig['services'][$service])) {
123 | // Merge the service descriptor with the default values
124 | $this->services[$service] = array_merge($this->services[$service], $apiConfig['services'][$service]);
125 | }
126 | }
127 |
128 | public function authenticate($code = null) {
129 | $service = $this->prepareService();
130 | $this->authenticated = true;
131 | return self::$auth->authenticate($service, $code);
132 | }
133 |
134 | /**
135 | * @return array
136 | * @visible For Testing
137 | */
138 | public function prepareService() {
139 | $service = array();
140 | $scopes = array();
141 | if ($this->scopes) {
142 | $scopes = $this->scopes;
143 | } else {
144 | foreach ($this->services as $key => $val) {
145 | if (isset($val['scope'])) {
146 | if (is_array($val['scope'])) {
147 | $scopes = array_merge($val['scope'], $scopes);
148 | } else {
149 | $scopes[] = $val['scope'];
150 | }
151 | } else {
152 | $scopes[] = 'https://www.googleapis.com/auth/' . $key;
153 | }
154 | unset($val['discoveryURI']);
155 | unset($val['scope']);
156 | $service = array_merge($service, $val);
157 | }
158 | }
159 | $service['scope'] = implode(' ', $scopes);
160 | return $service;
161 | }
162 |
163 | /**
164 | * Set the OAuth 2.0 access token using the string that resulted from calling authenticate()
165 | * or Google_Client#getAccessToken().
166 | * @param string $accessToken JSON encoded string containing in the following format:
167 | * {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer",
168 | * "expires_in":3600, "id_token":"TOKEN", "created":1320790426}
169 | */
170 | public function setAccessToken($accessToken) {
171 | if ($accessToken == null || 'null' == $accessToken) {
172 | $accessToken = null;
173 | }
174 | self::$auth->setAccessToken($accessToken);
175 | }
176 |
177 | /**
178 | * Set the type of Auth class the client should use.
179 | * @param string $authClassName
180 | */
181 | public function setAuthClass($authClassName) {
182 | self::$auth = new $authClassName();
183 | }
184 |
185 | /**
186 | * Construct the OAuth 2.0 authorization request URI.
187 | * @return string
188 | */
189 | public function createAuthUrl() {
190 | $service = $this->prepareService();
191 | return self::$auth->createAuthUrl($service['scope']);
192 | }
193 |
194 | /**
195 | * Get the OAuth 2.0 access token.
196 | * @return string $accessToken JSON encoded string in the following format:
197 | * {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer",
198 | * "expires_in":3600,"id_token":"TOKEN", "created":1320790426}
199 | */
200 | public function getAccessToken() {
201 | $token = self::$auth->getAccessToken();
202 | return (null == $token || 'null' == $token) ? null : $token;
203 | }
204 |
205 | /**
206 | * Returns if the access_token is expired.
207 | * @return bool Returns True if the access_token is expired.
208 | */
209 | public function isAccessTokenExpired() {
210 | return self::$auth->isAccessTokenExpired();
211 | }
212 |
213 | /**
214 | * Set the developer key to use, these are obtained through the API Console.
215 | * @see http://code.google.com/apis/console-help/#generatingdevkeys
216 | * @param string $developerKey
217 | */
218 | public function setDeveloperKey($developerKey) {
219 | self::$auth->setDeveloperKey($developerKey);
220 | }
221 |
222 | /**
223 | * Set OAuth 2.0 "state" parameter to achieve per-request customization.
224 | * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-3.1.2.2
225 | * @param string $state
226 | */
227 | public function setState($state) {
228 | self::$auth->setState($state);
229 | }
230 |
231 | /**
232 | * @param string $accessType Possible values for access_type include:
233 | * {@code "offline"} to request offline access from the user. (This is the default value)
234 | * {@code "online"} to request online access from the user.
235 | */
236 | public function setAccessType($accessType) {
237 | self::$auth->setAccessType($accessType);
238 | }
239 |
240 | /**
241 | * @param string $approvalPrompt Possible values for approval_prompt include:
242 | * {@code "force"} to force the approval UI to appear. (This is the default value)
243 | * {@code "auto"} to request auto-approval when possible.
244 | */
245 | public function setApprovalPrompt($approvalPrompt) {
246 | self::$auth->setApprovalPrompt($approvalPrompt);
247 | }
248 |
249 | /**
250 | * Set the application name, this is included in the User-Agent HTTP header.
251 | * @param string $applicationName
252 | */
253 | public function setApplicationName($applicationName) {
254 | global $apiConfig;
255 | $apiConfig['application_name'] = $applicationName;
256 | }
257 |
258 | /**
259 | * Set the OAuth 2.0 Client ID.
260 | * @param string $clientId
261 | */
262 | public function setClientId($clientId) {
263 | global $apiConfig;
264 | $apiConfig['oauth2_client_id'] = $clientId;
265 | self::$auth->clientId = $clientId;
266 | }
267 |
268 | /**
269 | * Get the OAuth 2.0 Client ID.
270 | */
271 | public function getClientId() {
272 | return self::$auth->clientId;
273 | }
274 |
275 | /**
276 | * Set the OAuth 2.0 Client Secret.
277 | * @param string $clientSecret
278 | */
279 | public function setClientSecret($clientSecret) {
280 | global $apiConfig;
281 | $apiConfig['oauth2_client_secret'] = $clientSecret;
282 | self::$auth->clientSecret = $clientSecret;
283 | }
284 |
285 | /**
286 | * Get the OAuth 2.0 Client Secret.
287 | */
288 | public function getClientSecret() {
289 | return self::$auth->clientSecret;
290 | }
291 |
292 | /**
293 | * Set the OAuth 2.0 Redirect URI.
294 | * @param string $redirectUri
295 | */
296 | public function setRedirectUri($redirectUri) {
297 | global $apiConfig;
298 | $apiConfig['oauth2_redirect_uri'] = $redirectUri;
299 | self::$auth->redirectUri = $redirectUri;
300 | }
301 |
302 | /**
303 | * Get the OAuth 2.0 Redirect URI.
304 | */
305 | public function getRedirectUri() {
306 | return self::$auth->redirectUri;
307 | }
308 |
309 | /**
310 | * Fetches a fresh OAuth 2.0 access token with the given refresh token.
311 | * @param string $refreshToken
312 | * @return void
313 | */
314 | public function refreshToken($refreshToken) {
315 | self::$auth->refreshToken($refreshToken);
316 | }
317 |
318 | /**
319 | * Revoke an OAuth2 access token or refresh token. This method will revoke the current access
320 | * token, if a token isn't provided.
321 | * @throws Google_AuthException
322 | * @param string|null $token The token (access token or a refresh token) that should be revoked.
323 | * @return boolean Returns True if the revocation was successful, otherwise False.
324 | */
325 | public function revokeToken($token = null) {
326 | self::$auth->revokeToken($token);
327 | }
328 |
329 | /**
330 | * Verify an id_token. This method will verify the current id_token, if one
331 | * isn't provided.
332 | * @throws Google_AuthException
333 | * @param string|null $token The token (id_token) that should be verified.
334 | * @return Google_LoginTicket Returns an apiLoginTicket if the verification was
335 | * successful.
336 | */
337 | public function verifyIdToken($token = null) {
338 | return self::$auth->verifyIdToken($token);
339 | }
340 |
341 | /**
342 | * @param Google_AssertionCredentials $creds
343 | * @return void
344 | */
345 | public function setAssertionCredentials(Google_AssertionCredentials $creds) {
346 | self::$auth->setAssertionCredentials($creds);
347 | }
348 |
349 | /**
350 | * This function allows you to overrule the automatically generated scopes,
351 | * so that you can ask for more or less permission in the auth flow
352 | * Set this before you call authenticate() though!
353 | * @param array $scopes, ie: array('https://www.googleapis.com/auth/plus.me', 'https://www.googleapis.com/auth/moderator')
354 | */
355 | public function setScopes($scopes) {
356 | $this->scopes = is_string($scopes) ? explode(" ", $scopes) : $scopes;
357 | }
358 |
359 | /**
360 | * Declare if objects should be returned by the api service classes.
361 | *
362 | * @param boolean $useObjects True if objects should be returned by the service classes.
363 | * False if associative arrays should be returned (default behavior).
364 | * @experimental
365 | */
366 | public function setUseObjects($useObjects) {
367 | global $apiConfig;
368 | $apiConfig['use_objects'] = $useObjects;
369 | }
370 |
371 | /**
372 | * Declare if objects should be returned by the api service classes.
373 | *
374 | * @param boolean $useBatch True if the experimental batch support should
375 | * be enabled. Defaults to False.
376 | * @experimental
377 | */
378 | public function setUseBatch($useBatch) {
379 | self::$useBatch = $useBatch;
380 | }
381 |
382 | /**
383 | * @static
384 | * @return Google_Auth the implementation of apiAuth.
385 | */
386 | public static function getAuth() {
387 | return Google_Client::$auth;
388 | }
389 |
390 | /**
391 | * @static
392 | * @return Google_IO the implementation of apiIo.
393 | */
394 | public static function getIo() {
395 | return Google_Client::$io;
396 | }
397 |
398 | /**
399 | * @return Google_Cache the implementation of apiCache.
400 | */
401 | public function getCache() {
402 | return Google_Client::$cache;
403 | }
404 | }
405 |
406 | // Exceptions that the Google PHP API Library can throw
407 | class Google_Exception extends Exception {}
408 | class Google_AuthException extends Google_Exception {}
409 | class Google_CacheException extends Google_Exception {}
410 | class Google_IOException extends Google_Exception {}
411 | class Google_ServiceException extends Google_Exception {
412 | /**
413 | * Optional list of errors returned in a JSON body of an HTTP error response.
414 | */
415 | protected $errors = array();
416 |
417 | /**
418 | * Override default constructor to add ability to set $errors.
419 | *
420 | * @param string $message
421 | * @param int $code
422 | * @param Exception|null $previous
423 | * @param [{string, string}] errors List of errors returned in an HTTP
424 | * response. Defaults to [].
425 | */
426 | public function __construct($message, $code = 0, Exception $previous = null,
427 | $errors = array()) {
428 | if(version_compare(PHP_VERSION, '5.3.0') >= 0) {
429 | parent::__construct($message, $code, $previous);
430 | } else {
431 | parent::__construct($message, $code);
432 | }
433 |
434 | $this->errors = $errors;
435 | }
436 |
437 | /**
438 | * An example of the possible errors returned.
439 | *
440 | * {
441 | * "domain": "global",
442 | * "reason": "authError",
443 | * "message": "Invalid Credentials",
444 | * "locationType": "header",
445 | * "location": "Authorization",
446 | * }
447 | *
448 | * @return [{string, string}] List of errors return in an HTTP response or [].
449 | */
450 | public function getErrors() {
451 | return $this->errors;
452 | }
453 | }
454 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/auth/Google_AssertionCredentials.php:
--------------------------------------------------------------------------------
1 |
22 | */
23 | class Google_AssertionCredentials {
24 | const MAX_TOKEN_LIFETIME_SECS = 3600;
25 |
26 | public $serviceAccountName;
27 | public $scopes;
28 | public $privateKey;
29 | public $privateKeyPassword;
30 | public $assertionType;
31 | public $prn;
32 |
33 | /**
34 | * @param $serviceAccountName
35 | * @param $scopes array List of scopes
36 | * @param $privateKey
37 | * @param string $privateKeyPassword
38 | * @param string $assertionType
39 | * @param bool|string $prn The email address of the user for which the
40 | * application is requesting delegated access.
41 | */
42 | public function __construct(
43 | $serviceAccountName,
44 | $scopes,
45 | $privateKey,
46 | $privateKeyPassword = 'notasecret',
47 | $assertionType = 'http://oauth.net/grant_type/jwt/1.0/bearer',
48 | $prn = false) {
49 | $this->serviceAccountName = $serviceAccountName;
50 | $this->scopes = is_string($scopes) ? $scopes : implode(' ', $scopes);
51 | $this->privateKey = $privateKey;
52 | $this->privateKeyPassword = $privateKeyPassword;
53 | $this->assertionType = $assertionType;
54 | $this->prn = $prn;
55 | }
56 |
57 | public function generateAssertion() {
58 | $now = time();
59 |
60 | $jwtParams = array(
61 | 'aud' => Google_OAuth2::OAUTH2_TOKEN_URI,
62 | 'scope' => $this->scopes,
63 | 'iat' => $now,
64 | 'exp' => $now + self::MAX_TOKEN_LIFETIME_SECS,
65 | 'iss' => $this->serviceAccountName,
66 | );
67 |
68 | if ($this->prn !== false) {
69 | $jwtParams['prn'] = $this->prn;
70 | }
71 |
72 | return $this->makeSignedJwt($jwtParams);
73 | }
74 |
75 | /**
76 | * Creates a signed JWT.
77 | * @param array $payload
78 | * @return string The signed JWT.
79 | */
80 | private function makeSignedJwt($payload) {
81 | $header = array('typ' => 'JWT', 'alg' => 'RS256');
82 |
83 | $segments = array(
84 | Google_Utils::urlSafeB64Encode(json_encode($header)),
85 | Google_Utils::urlSafeB64Encode(json_encode($payload))
86 | );
87 |
88 | $signingInput = implode('.', $segments);
89 | $signer = new Google_P12Signer($this->privateKey, $this->privateKeyPassword);
90 | $signature = $signer->sign($signingInput);
91 | $segments[] = Google_Utils::urlSafeB64Encode($signature);
92 |
93 | return implode(".", $segments);
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/auth/Google_Auth.php:
--------------------------------------------------------------------------------
1 |
24 | *
25 | */
26 | abstract class Google_Auth {
27 | abstract public function authenticate($service);
28 | abstract public function sign(Google_HttpRequest $request);
29 | abstract public function createAuthUrl($scope);
30 |
31 | abstract public function getAccessToken();
32 | abstract public function setAccessToken($accessToken);
33 | abstract public function setDeveloperKey($developerKey);
34 | abstract public function refreshToken($refreshToken);
35 | abstract public function revokeToken();
36 | }
37 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/auth/Google_AuthNone.php:
--------------------------------------------------------------------------------
1 |
21 | * @author Chirag Shah
22 | */
23 | class Google_AuthNone extends Google_Auth {
24 | public $key = null;
25 |
26 | public function __construct() {
27 | global $apiConfig;
28 | if (!empty($apiConfig['developer_key'])) {
29 | $this->setDeveloperKey($apiConfig['developer_key']);
30 | }
31 | }
32 |
33 | public function setDeveloperKey($key) {$this->key = $key;}
34 | public function authenticate($service) {/*noop*/}
35 | public function setAccessToken($accessToken) {/* noop*/}
36 | public function getAccessToken() {return null;}
37 | public function createAuthUrl($scope) {return null;}
38 | public function refreshToken($refreshToken) {/* noop*/}
39 | public function revokeToken() {/* noop*/}
40 |
41 | public function sign(Google_HttpRequest $request) {
42 | if ($this->key) {
43 | $request->setUrl($request->getUrl() . ((strpos($request->getUrl(), '?') === false) ? '?' : '&')
44 | . 'key='.urlencode($this->key));
45 | }
46 | return $request;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/auth/Google_LoginTicket.php:
--------------------------------------------------------------------------------
1 |
22 | */
23 | class Google_LoginTicket {
24 | const USER_ATTR = "id";
25 |
26 | // Information from id token envelope.
27 | private $envelope;
28 |
29 | // Information from id token payload.
30 | private $payload;
31 |
32 | /**
33 | * Creates a user based on the supplied token.
34 | *
35 | * @param string $envelope Header from a verified authentication token.
36 | * @param string $payload Information from a verified authentication token.
37 | */
38 | public function __construct($envelope, $payload) {
39 | $this->envelope = $envelope;
40 | $this->payload = $payload;
41 | }
42 |
43 | /**
44 | * Returns the numeric identifier for the user.
45 | * @throws Google_AuthException
46 | * @return
47 | */
48 | public function getUserId() {
49 | if (array_key_exists(self::USER_ATTR, $this->payload)) {
50 | return $this->payload[self::USER_ATTR];
51 | }
52 | throw new Google_AuthException("No user_id in token");
53 | }
54 |
55 | /**
56 | * Returns attributes from the login ticket. This can contain
57 | * various information about the user session.
58 | * @return array
59 | */
60 | public function getAttributes() {
61 | return array("envelope" => $this->envelope, "payload" => $this->payload);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/auth/Google_OAuth2.php:
--------------------------------------------------------------------------------
1 |
26 | * @author Chirag Shah
27 | *
28 | */
29 | class Google_OAuth2 extends Google_Auth {
30 | public $clientId;
31 | public $clientSecret;
32 | public $developerKey;
33 | public $token;
34 | public $redirectUri;
35 | public $state;
36 | public $accessType = 'offline';
37 | public $approvalPrompt = 'force';
38 |
39 | /** @var Google_AssertionCredentials $assertionCredentials */
40 | public $assertionCredentials;
41 |
42 | const OAUTH2_REVOKE_URI = 'https://accounts.google.com/o/oauth2/revoke';
43 | const OAUTH2_TOKEN_URI = 'https://accounts.google.com/o/oauth2/token';
44 | const OAUTH2_AUTH_URL = 'https://accounts.google.com/o/oauth2/auth';
45 | const OAUTH2_FEDERATED_SIGNON_CERTS_URL = 'https://www.googleapis.com/oauth2/v1/certs';
46 | const CLOCK_SKEW_SECS = 300; // five minutes in seconds
47 | const AUTH_TOKEN_LIFETIME_SECS = 300; // five minutes in seconds
48 | const MAX_TOKEN_LIFETIME_SECS = 86400; // one day in seconds
49 |
50 | /**
51 | * Instantiates the class, but does not initiate the login flow, leaving it
52 | * to the discretion of the caller (which is done by calling authenticate()).
53 | */
54 | public function __construct() {
55 | global $apiConfig;
56 |
57 | if (! empty($apiConfig['developer_key'])) {
58 | $this->developerKey = $apiConfig['developer_key'];
59 | }
60 |
61 | if (! empty($apiConfig['oauth2_client_id'])) {
62 | $this->clientId = $apiConfig['oauth2_client_id'];
63 | }
64 |
65 | if (! empty($apiConfig['oauth2_client_secret'])) {
66 | $this->clientSecret = $apiConfig['oauth2_client_secret'];
67 | }
68 |
69 | if (! empty($apiConfig['oauth2_redirect_uri'])) {
70 | $this->redirectUri = $apiConfig['oauth2_redirect_uri'];
71 | }
72 |
73 | if (! empty($apiConfig['oauth2_access_type'])) {
74 | $this->accessType = $apiConfig['oauth2_access_type'];
75 | }
76 |
77 | if (! empty($apiConfig['oauth2_approval_prompt'])) {
78 | $this->approvalPrompt = $apiConfig['oauth2_approval_prompt'];
79 | }
80 | }
81 |
82 | /**
83 | * @param $service
84 | * @param string|null $code
85 | * @throws Google_AuthException
86 | * @return string
87 | */
88 | public function authenticate($service, $code = null) {
89 | if (!$code && isset($_GET['code'])) {
90 | $code = $_GET['code'];
91 | }
92 |
93 | if ($code) {
94 | // We got here from the redirect from a successful authorization grant, fetch the access token
95 | $request = Google_Client::$io->makeRequest(new Google_HttpRequest(self::OAUTH2_TOKEN_URI, 'POST', array(), array(
96 | 'code' => $code,
97 | 'grant_type' => 'authorization_code',
98 | 'redirect_uri' => $this->redirectUri,
99 | 'client_id' => $this->clientId,
100 | 'client_secret' => $this->clientSecret
101 | )));
102 |
103 | if ($request->getResponseHttpCode() == 200) {
104 | $this->setAccessToken($request->getResponseBody());
105 | $this->token['created'] = time();
106 | return $this->getAccessToken();
107 | } else {
108 | $response = $request->getResponseBody();
109 | $decodedResponse = json_decode($response, true);
110 | if ($decodedResponse != null && $decodedResponse['error']) {
111 | $response = $decodedResponse['error'];
112 | }
113 | throw new Google_AuthException("Error fetching OAuth2 access token, message: '$response'", $request->getResponseHttpCode());
114 | }
115 | }
116 |
117 | $authUrl = $this->createAuthUrl($service['scope']);
118 | header('Location: ' . $authUrl);
119 | return true;
120 | }
121 |
122 | /**
123 | * Create a URL to obtain user authorization.
124 | * The authorization endpoint allows the user to first
125 | * authenticate, and then grant/deny the access request.
126 | * @param string $scope The scope is expressed as a list of space-delimited strings.
127 | * @return string
128 | */
129 | public function createAuthUrl($scope) {
130 | $params = array(
131 | 'response_type=code',
132 | 'redirect_uri=' . urlencode($this->redirectUri),
133 | 'client_id=' . urlencode($this->clientId),
134 | 'scope=' . urlencode($scope),
135 | 'access_type=' . urlencode($this->accessType),
136 | 'approval_prompt=' . urlencode($this->approvalPrompt)
137 | );
138 |
139 | if (isset($this->state)) {
140 | $params[] = 'state=' . urlencode($this->state);
141 | }
142 | $params = implode('&', $params);
143 | return self::OAUTH2_AUTH_URL . "?$params";
144 | }
145 |
146 | /**
147 | * @param string $token
148 | * @throws Google_AuthException
149 | */
150 | public function setAccessToken($token) {
151 | $token = json_decode($token, true);
152 | if ($token == null) {
153 | throw new Google_AuthException('Could not json decode the token');
154 | }
155 | if (! isset($token['access_token'])) {
156 | throw new Google_AuthException("Invalid token format");
157 | }
158 | $this->token = $token;
159 | }
160 |
161 | public function getAccessToken() {
162 | return json_encode($this->token);
163 | }
164 |
165 | public function setDeveloperKey($developerKey) {
166 | $this->developerKey = $developerKey;
167 | }
168 |
169 | public function setState($state) {
170 | $this->state = $state;
171 | }
172 |
173 | public function setAccessType($accessType) {
174 | $this->accessType = $accessType;
175 | }
176 |
177 | public function setApprovalPrompt($approvalPrompt) {
178 | $this->approvalPrompt = $approvalPrompt;
179 | }
180 |
181 | public function setAssertionCredentials(Google_AssertionCredentials $creds) {
182 | $this->assertionCredentials = $creds;
183 | }
184 |
185 | /**
186 | * Include an accessToken in a given apiHttpRequest.
187 | * @param Google_HttpRequest $request
188 | * @return Google_HttpRequest
189 | * @throws Google_AuthException
190 | */
191 | public function sign(Google_HttpRequest $request) {
192 | // add the developer key to the request before signing it
193 | if ($this->developerKey) {
194 | $requestUrl = $request->getUrl();
195 | $requestUrl .= (strpos($request->getUrl(), '?') === false) ? '?' : '&';
196 | $requestUrl .= 'key=' . urlencode($this->developerKey);
197 | $request->setUrl($requestUrl);
198 | }
199 |
200 | // Cannot sign the request without an OAuth access token.
201 | if (null == $this->token && null == $this->assertionCredentials) {
202 | return $request;
203 | }
204 |
205 | // Check if the token is set to expire in the next 30 seconds
206 | // (or has already expired).
207 | if ($this->isAccessTokenExpired()) {
208 | if ($this->assertionCredentials) {
209 | $this->refreshTokenWithAssertion();
210 | } else {
211 | if (! array_key_exists('refresh_token', $this->token)) {
212 | throw new Google_AuthException("The OAuth 2.0 access token has expired, "
213 | . "and a refresh token is not available. Refresh tokens are not "
214 | . "returned for responses that were auto-approved.");
215 | }
216 | $this->refreshToken($this->token['refresh_token']);
217 | }
218 | }
219 |
220 | // Add the OAuth2 header to the request
221 | $request->setRequestHeaders(
222 | array('Authorization' => 'Bearer ' . $this->token['access_token'])
223 | );
224 |
225 | return $request;
226 | }
227 |
228 | /**
229 | * Fetches a fresh access token with the given refresh token.
230 | * @param string $refreshToken
231 | * @return void
232 | */
233 | public function refreshToken($refreshToken) {
234 | $this->refreshTokenRequest(array(
235 | 'client_id' => $this->clientId,
236 | 'client_secret' => $this->clientSecret,
237 | 'refresh_token' => $refreshToken,
238 | 'grant_type' => 'refresh_token'
239 | ));
240 | }
241 |
242 | /**
243 | * Fetches a fresh access token with a given assertion token.
244 | * @param Google_AssertionCredentials $assertionCredentials optional.
245 | * @return void
246 | */
247 | public function refreshTokenWithAssertion($assertionCredentials = null) {
248 | if (!$assertionCredentials) {
249 | $assertionCredentials = $this->assertionCredentials;
250 | }
251 |
252 | $this->refreshTokenRequest(array(
253 | 'grant_type' => 'assertion',
254 | 'assertion_type' => $assertionCredentials->assertionType,
255 | 'assertion' => $assertionCredentials->generateAssertion(),
256 | ));
257 | }
258 |
259 | private function refreshTokenRequest($params) {
260 | $http = new Google_HttpRequest(self::OAUTH2_TOKEN_URI, 'POST', array(), $params);
261 | $request = Google_Client::$io->makeRequest($http);
262 |
263 | $code = $request->getResponseHttpCode();
264 | $body = $request->getResponseBody();
265 | if (200 == $code) {
266 | $token = json_decode($body, true);
267 | if ($token == null) {
268 | throw new Google_AuthException("Could not json decode the access token");
269 | }
270 |
271 | if (! isset($token['access_token']) || ! isset($token['expires_in'])) {
272 | throw new Google_AuthException("Invalid token format");
273 | }
274 |
275 | $this->token['access_token'] = $token['access_token'];
276 | $this->token['expires_in'] = $token['expires_in'];
277 | $this->token['created'] = time();
278 | } else {
279 | throw new Google_AuthException("Error refreshing the OAuth2 token, message: '$body'", $code);
280 | }
281 | }
282 |
283 | /**
284 | * Revoke an OAuth2 access token or refresh token. This method will revoke the current access
285 | * token, if a token isn't provided.
286 | * @throws Google_AuthException
287 | * @param string|null $token The token (access token or a refresh token) that should be revoked.
288 | * @return boolean Returns True if the revocation was successful, otherwise False.
289 | */
290 | public function revokeToken($token = null) {
291 | if (!$token) {
292 | $token = $this->token['access_token'];
293 | }
294 | $request = new Google_HttpRequest(self::OAUTH2_REVOKE_URI, 'POST', array(), "token=$token");
295 | $response = Google_Client::$io->makeRequest($request);
296 | $code = $response->getResponseHttpCode();
297 | if ($code == 200) {
298 | $this->token = null;
299 | return true;
300 | }
301 |
302 | return false;
303 | }
304 |
305 | /**
306 | * Returns if the access_token is expired.
307 | * @return bool Returns True if the access_token is expired.
308 | */
309 | public function isAccessTokenExpired() {
310 | if (null == $this->token) {
311 | return true;
312 | }
313 |
314 | // If the token is set to expire in the next 30 seconds.
315 | $expired = ($this->token['created']
316 | + ($this->token['expires_in'] - 30)) < time();
317 |
318 | return $expired;
319 | }
320 |
321 | // Gets federated sign-on certificates to use for verifying identity tokens.
322 | // Returns certs as array structure, where keys are key ids, and values
323 | // are PEM encoded certificates.
324 | private function getFederatedSignOnCerts() {
325 | // This relies on makeRequest caching certificate responses.
326 | $request = Google_Client::$io->makeRequest(new Google_HttpRequest(
327 | self::OAUTH2_FEDERATED_SIGNON_CERTS_URL));
328 | if ($request->getResponseHttpCode() == 200) {
329 | $certs = json_decode($request->getResponseBody(), true);
330 | if ($certs) {
331 | return $certs;
332 | }
333 | }
334 | throw new Google_AuthException(
335 | "Failed to retrieve verification certificates: '" .
336 | $request->getResponseBody() . "'.",
337 | $request->getResponseHttpCode());
338 | }
339 |
340 | /**
341 | * Verifies an id token and returns the authenticated apiLoginTicket.
342 | * Throws an exception if the id token is not valid.
343 | * The audience parameter can be used to control which id tokens are
344 | * accepted. By default, the id token must have been issued to this OAuth2 client.
345 | *
346 | * @param $id_token
347 | * @param $audience
348 | * @return Google_LoginTicket
349 | */
350 | public function verifyIdToken($id_token = null, $audience = null) {
351 | if (!$id_token) {
352 | $id_token = $this->token['id_token'];
353 | }
354 |
355 | $certs = $this->getFederatedSignonCerts();
356 | if (!$audience) {
357 | $audience = $this->clientId;
358 | }
359 | return $this->verifySignedJwtWithCerts($id_token, $certs, $audience);
360 | }
361 |
362 | // Verifies the id token, returns the verified token contents.
363 | // Visible for testing.
364 | function verifySignedJwtWithCerts($jwt, $certs, $required_audience) {
365 | $segments = explode(".", $jwt);
366 | if (count($segments) != 3) {
367 | throw new Google_AuthException("Wrong number of segments in token: $jwt");
368 | }
369 | $signed = $segments[0] . "." . $segments[1];
370 | $signature = Google_Utils::urlSafeB64Decode($segments[2]);
371 |
372 | // Parse envelope.
373 | $envelope = json_decode(Google_Utils::urlSafeB64Decode($segments[0]), true);
374 | if (!$envelope) {
375 | throw new Google_AuthException("Can't parse token envelope: " . $segments[0]);
376 | }
377 |
378 | // Parse token
379 | $json_body = Google_Utils::urlSafeB64Decode($segments[1]);
380 | $payload = json_decode($json_body, true);
381 | if (!$payload) {
382 | throw new Google_AuthException("Can't parse token payload: " . $segments[1]);
383 | }
384 |
385 | // Check signature
386 | $verified = false;
387 | foreach ($certs as $keyName => $pem) {
388 | $public_key = new Google_PemVerifier($pem);
389 | if ($public_key->verify($signed, $signature)) {
390 | $verified = true;
391 | break;
392 | }
393 | }
394 |
395 | if (!$verified) {
396 | throw new Google_AuthException("Invalid token signature: $jwt");
397 | }
398 |
399 | // Check issued-at timestamp
400 | $iat = 0;
401 | if (array_key_exists("iat", $payload)) {
402 | $iat = $payload["iat"];
403 | }
404 | if (!$iat) {
405 | throw new Google_AuthException("No issue time in token: $json_body");
406 | }
407 | $earliest = $iat - self::CLOCK_SKEW_SECS;
408 |
409 | // Check expiration timestamp
410 | $now = time();
411 | $exp = 0;
412 | if (array_key_exists("exp", $payload)) {
413 | $exp = $payload["exp"];
414 | }
415 | if (!$exp) {
416 | throw new Google_AuthException("No expiration time in token: $json_body");
417 | }
418 | if ($exp >= $now + self::MAX_TOKEN_LIFETIME_SECS) {
419 | throw new Google_AuthException(
420 | "Expiration time too far in future: $json_body");
421 | }
422 |
423 | $latest = $exp + self::CLOCK_SKEW_SECS;
424 | if ($now < $earliest) {
425 | throw new Google_AuthException(
426 | "Token used too early, $now < $earliest: $json_body");
427 | }
428 | if ($now > $latest) {
429 | throw new Google_AuthException(
430 | "Token used too late, $now > $latest: $json_body");
431 | }
432 |
433 | // TODO(beaton): check issuer field?
434 |
435 | // Check audience
436 | $aud = $payload["aud"];
437 | if ($aud != $required_audience) {
438 | throw new Google_AuthException("Wrong recipient, $aud != $required_audience: $json_body");
439 | }
440 |
441 | // All good.
442 | return new Google_LoginTicket($envelope, $payload);
443 | }
444 | }
445 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/auth/Google_P12Signer.php:
--------------------------------------------------------------------------------
1 |
24 | */
25 | class Google_P12Signer extends Google_Signer {
26 | // OpenSSL private key resource
27 | private $privateKey;
28 |
29 | // Creates a new signer from a .p12 file.
30 | function __construct($p12, $password) {
31 | if (!function_exists('openssl_x509_read')) {
32 | throw new Exception(
33 | 'The Google PHP API library needs the openssl PHP extension');
34 | }
35 |
36 | // This throws on error
37 | $certs = array();
38 | if (!openssl_pkcs12_read($p12, $certs, $password)) {
39 | throw new Google_AuthException("Unable to parse the p12 file. " .
40 | "Is this a .p12 file? Is the password correct? OpenSSL error: " .
41 | openssl_error_string());
42 | }
43 | // TODO(beaton): is this part of the contract for the openssl_pkcs12_read
44 | // method? What happens if there are multiple private keys? Do we care?
45 | if (!array_key_exists("pkey", $certs) || !$certs["pkey"]) {
46 | throw new Google_AuthException("No private key found in p12 file.");
47 | }
48 | $this->privateKey = openssl_pkey_get_private($certs["pkey"]);
49 | if (!$this->privateKey) {
50 | throw new Google_AuthException("Unable to load private key in ");
51 | }
52 | }
53 |
54 | function __destruct() {
55 | if ($this->privateKey) {
56 | openssl_pkey_free($this->privateKey);
57 | }
58 | }
59 |
60 | function sign($data) {
61 | if(version_compare(PHP_VERSION, '5.3.0') < 0) {
62 | throw new Google_AuthException(
63 | "PHP 5.3.0 or higher is required to use service accounts.");
64 | }
65 | if (!openssl_sign($data, $signature, $this->privateKey, "sha256")) {
66 | throw new Google_AuthException("Unable to sign data");
67 | }
68 | return $signature;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/auth/Google_PemVerifier.php:
--------------------------------------------------------------------------------
1 |
22 | */
23 | class Google_PemVerifier extends Google_Verifier {
24 | private $publicKey;
25 |
26 | /**
27 | * Constructs a verifier from the supplied PEM-encoded certificate.
28 | *
29 | * $pem: a PEM encoded certificate (not a file).
30 | * @param $pem
31 | * @throws Google_AuthException
32 | * @throws Google_Exception
33 | */
34 | function __construct($pem) {
35 | if (!function_exists('openssl_x509_read')) {
36 | throw new Google_Exception('Google API PHP client needs the openssl PHP extension');
37 | }
38 | $this->publicKey = openssl_x509_read($pem);
39 | if (!$this->publicKey) {
40 | throw new Google_AuthException("Unable to parse PEM: $pem");
41 | }
42 | }
43 |
44 | function __destruct() {
45 | if ($this->publicKey) {
46 | openssl_x509_free($this->publicKey);
47 | }
48 | }
49 |
50 | /**
51 | * Verifies the signature on data.
52 | *
53 | * Returns true if the signature is valid, false otherwise.
54 | * @param $data
55 | * @param $signature
56 | * @throws Google_AuthException
57 | * @return bool
58 | */
59 | function verify($data, $signature) {
60 | $status = openssl_verify($data, $signature, $this->publicKey, "sha256");
61 | if ($status === -1) {
62 | throw new Google_AuthException('Signature verification error: ' . openssl_error_string());
63 | }
64 | return $status === 1;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/auth/Google_Signer.php:
--------------------------------------------------------------------------------
1 |
24 | */
25 | abstract class Google_Signer {
26 | /**
27 | * Signs data, returns the signature as binary data.
28 | */
29 | abstract public function sign($data);
30 | }
31 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/auth/Google_Verifier.php:
--------------------------------------------------------------------------------
1 |
24 | */
25 | abstract class Google_Verifier {
26 | /**
27 | * Checks a signature, returns true if the signature is correct,
28 | * false otherwise.
29 | */
30 | abstract public function verify($data, $signature);
31 | }
32 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/cache/Google_ApcCache.php:
--------------------------------------------------------------------------------
1 |
25 | */
26 | class googleApcCache extends Google_Cache {
27 |
28 | public function __construct() {
29 | if (! function_exists('apc_add')) {
30 | throw new Google_CacheException("Apc functions not available");
31 | }
32 | }
33 |
34 | private function isLocked($key) {
35 | if ((@apc_fetch($key . '.lock')) === false) {
36 | return false;
37 | }
38 | return true;
39 | }
40 |
41 | private function createLock($key) {
42 | // the interesting thing is that this could fail if the lock was created in the meantime..
43 | // but we'll ignore that out of convenience
44 | @apc_add($key . '.lock', '', 5);
45 | }
46 |
47 | private function removeLock($key) {
48 | // suppress all warnings, if some other process removed it that's ok too
49 | @apc_delete($key . '.lock');
50 | }
51 |
52 | private function waitForLock($key) {
53 | // 20 x 250 = 5 seconds
54 | $tries = 20;
55 | $cnt = 0;
56 | do {
57 | // 250 ms is a long time to sleep, but it does stop the server from burning all resources on polling locks..
58 | usleep(250);
59 | $cnt ++;
60 | } while ($cnt <= $tries && $this->isLocked($key));
61 | if ($this->isLocked($key)) {
62 | // 5 seconds passed, assume the owning process died off and remove it
63 | $this->removeLock($key);
64 | }
65 | }
66 |
67 | /**
68 | * @inheritDoc
69 | */
70 | public function get($key, $expiration = false) {
71 |
72 | if (($ret = @apc_fetch($key)) === false) {
73 | return false;
74 | }
75 | if (!$expiration || (time() - $ret['time'] > $expiration)) {
76 | $this->delete($key);
77 | return false;
78 | }
79 | return unserialize($ret['data']);
80 | }
81 |
82 | /**
83 | * @inheritDoc
84 | */
85 | public function set($key, $value) {
86 | if (@apc_store($key, array('time' => time(), 'data' => serialize($value))) == false) {
87 | throw new Google_CacheException("Couldn't store data");
88 | }
89 | }
90 |
91 | /**
92 | * @inheritDoc
93 | * @param String $key
94 | */
95 | public function delete($key) {
96 | @apc_delete($key);
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/cache/Google_Cache.php:
--------------------------------------------------------------------------------
1 |
25 | */
26 | abstract class Google_Cache {
27 |
28 | /**
29 | * Retrieves the data for the given key, or false if they
30 | * key is unknown or expired
31 | *
32 | * @param String $key The key who's data to retrieve
33 | * @param boolean|int $expiration Expiration time in seconds
34 | *
35 | */
36 | abstract function get($key, $expiration = false);
37 |
38 | /**
39 | * Store the key => $value set. The $value is serialized
40 | * by this function so can be of any type
41 | *
42 | * @param string $key Key of the data
43 | * @param string $value data
44 | */
45 | abstract function set($key, $value);
46 |
47 | /**
48 | * Removes the key/data pair for the given $key
49 | *
50 | * @param String $key
51 | */
52 | abstract function delete($key);
53 | }
54 |
55 |
56 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/cache/Google_FileCache.php:
--------------------------------------------------------------------------------
1 |
26 | */
27 | class Google_FileCache extends Google_Cache {
28 | private $path;
29 |
30 | public function __construct() {
31 | global $apiConfig;
32 | $this->path = $apiConfig['ioFileCache_directory'];
33 | }
34 |
35 | private function isLocked($storageFile) {
36 | // our lock file convention is simple: /the/file/path.lock
37 | return file_exists($storageFile . '.lock');
38 | }
39 |
40 | private function createLock($storageFile) {
41 | $storageDir = dirname($storageFile);
42 | if (! is_dir($storageDir)) {
43 | // @codeCoverageIgnoreStart
44 | if (! @mkdir($storageDir, 0755, true)) {
45 | // make sure the failure isn't because of a concurrency issue
46 | if (! is_dir($storageDir)) {
47 | throw new Google_CacheException("Could not create storage directory: $storageDir");
48 | }
49 | }
50 | // @codeCoverageIgnoreEnd
51 | }
52 | @touch($storageFile . '.lock');
53 | }
54 |
55 | private function removeLock($storageFile) {
56 | // suppress all warnings, if some other process removed it that's ok too
57 | @unlink($storageFile . '.lock');
58 | }
59 |
60 | private function waitForLock($storageFile) {
61 | // 20 x 250 = 5 seconds
62 | $tries = 20;
63 | $cnt = 0;
64 | do {
65 | // make sure PHP picks up on file changes. This is an expensive action but really can't be avoided
66 | clearstatcache();
67 | // 250 ms is a long time to sleep, but it does stop the server from burning all resources on polling locks..
68 | usleep(250);
69 | $cnt ++;
70 | } while ($cnt <= $tries && $this->isLocked($storageFile));
71 | if ($this->isLocked($storageFile)) {
72 | // 5 seconds passed, assume the owning process died off and remove it
73 | $this->removeLock($storageFile);
74 | }
75 | }
76 |
77 | private function getCacheDir($hash) {
78 | // use the first 2 characters of the hash as a directory prefix
79 | // this should prevent slowdowns due to huge directory listings
80 | // and thus give some basic amount of scalability
81 | return $this->path . '/' . substr($hash, 0, 2);
82 | }
83 |
84 | private function getCacheFile($hash) {
85 | return $this->getCacheDir($hash) . '/' . $hash;
86 | }
87 |
88 | public function get($key, $expiration = false) {
89 | $storageFile = $this->getCacheFile(md5($key));
90 | // See if this storage file is locked, if so we wait upto 5 seconds for the lock owning process to
91 | // complete it's work. If the lock is not released within that time frame, it's cleaned up.
92 | // This should give us a fair amount of 'Cache Stampeding' protection
93 | if ($this->isLocked($storageFile)) {
94 | $this->waitForLock($storageFile);
95 | }
96 | if (file_exists($storageFile) && is_readable($storageFile)) {
97 | $now = time();
98 | if (! $expiration || (($mtime = @filemtime($storageFile)) !== false && ($now - $mtime) < $expiration)) {
99 | if (($data = @file_get_contents($storageFile)) !== false) {
100 | $data = unserialize($data);
101 | return $data;
102 | }
103 | }
104 | }
105 | return false;
106 | }
107 |
108 | public function set($key, $value) {
109 | $storageDir = $this->getCacheDir(md5($key));
110 | $storageFile = $this->getCacheFile(md5($key));
111 | if ($this->isLocked($storageFile)) {
112 | // some other process is writing to this file too, wait until it's done to prevent hickups
113 | $this->waitForLock($storageFile);
114 | }
115 | if (! is_dir($storageDir)) {
116 | if (! @mkdir($storageDir, 0755, true)) {
117 | throw new Google_CacheException("Could not create storage directory: $storageDir");
118 | }
119 | }
120 | // we serialize the whole request object, since we don't only want the
121 | // responseContent but also the postBody used, headers, size, etc
122 | $data = serialize($value);
123 | $this->createLock($storageFile);
124 | if (! @file_put_contents($storageFile, $data)) {
125 | $this->removeLock($storageFile);
126 | throw new Google_CacheException("Could not store data in the file");
127 | }
128 | $this->removeLock($storageFile);
129 | }
130 |
131 | public function delete($key) {
132 | $file = $this->getCacheFile(md5($key));
133 | if (! @unlink($file)) {
134 | throw new Google_CacheException("Cache file could not be deleted");
135 | }
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/cache/Google_MemcacheCache.php:
--------------------------------------------------------------------------------
1 |
25 | */
26 | class Google_MemcacheCache extends Google_Cache {
27 | private $connection = false;
28 |
29 | public function __construct() {
30 | global $apiConfig;
31 | if (! function_exists('memcache_connect')) {
32 | throw new Google_CacheException("Memcache functions not available");
33 | }
34 | $this->host = $apiConfig['ioMemCacheCache_host'];
35 | $this->port = $apiConfig['ioMemCacheCache_port'];
36 | if (empty($this->host) || empty($this->port)) {
37 | throw new Google_CacheException("You need to supply a valid memcache host and port");
38 | }
39 | }
40 |
41 | private function isLocked($key) {
42 | $this->check();
43 | if ((@memcache_get($this->connection, $key . '.lock')) === false) {
44 | return false;
45 | }
46 | return true;
47 | }
48 |
49 | private function createLock($key) {
50 | $this->check();
51 | // the interesting thing is that this could fail if the lock was created in the meantime..
52 | // but we'll ignore that out of convenience
53 | @memcache_add($this->connection, $key . '.lock', '', 0, 5);
54 | }
55 |
56 | private function removeLock($key) {
57 | $this->check();
58 | // suppress all warnings, if some other process removed it that's ok too
59 | @memcache_delete($this->connection, $key . '.lock');
60 | }
61 |
62 | private function waitForLock($key) {
63 | $this->check();
64 | // 20 x 250 = 5 seconds
65 | $tries = 20;
66 | $cnt = 0;
67 | do {
68 | // 250 ms is a long time to sleep, but it does stop the server from burning all resources on polling locks..
69 | usleep(250);
70 | $cnt ++;
71 | } while ($cnt <= $tries && $this->isLocked($key));
72 | if ($this->isLocked($key)) {
73 | // 5 seconds passed, assume the owning process died off and remove it
74 | $this->removeLock($key);
75 | }
76 | }
77 |
78 | // I prefer lazy initialization since the cache isn't used every request
79 | // so this potentially saves a lot of overhead
80 | private function connect() {
81 | if (! $this->connection = @memcache_pconnect($this->host, $this->port)) {
82 | throw new Google_CacheException("Couldn't connect to memcache server");
83 | }
84 | }
85 |
86 | private function check() {
87 | if (! $this->connection) {
88 | $this->connect();
89 | }
90 | }
91 |
92 | /**
93 | * @inheritDoc
94 | */
95 | public function get($key, $expiration = false) {
96 | $this->check();
97 | if (($ret = @memcache_get($this->connection, $key)) === false) {
98 | return false;
99 | }
100 | if (! $expiration || (time() - $ret['time'] > $expiration)) {
101 | $this->delete($key);
102 | return false;
103 | }
104 | return $ret['data'];
105 | }
106 |
107 | /**
108 | * @inheritDoc
109 | * @param string $key
110 | * @param string $value
111 | * @throws Google_CacheException
112 | */
113 | public function set($key, $value) {
114 | $this->check();
115 | // we store it with the cache_time default expiration so objects will at least get cleaned eventually.
116 | if (@memcache_set($this->connection, $key, array('time' => time(),
117 | 'data' => $value), false) == false) {
118 | throw new Google_CacheException("Couldn't store data in cache");
119 | }
120 | }
121 |
122 | /**
123 | * @inheritDoc
124 | * @param String $key
125 | */
126 | public function delete($key) {
127 | $this->check();
128 | @memcache_delete($this->connection, $key);
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/config.php:
--------------------------------------------------------------------------------
1 | false,
23 |
24 | // The application_name is included in the User-Agent HTTP header.
25 | 'application_name' => '',
26 |
27 | // OAuth2 Settings, you can get these keys at https://code.google.com/apis/console
28 | 'oauth2_client_id' => '',
29 | 'oauth2_client_secret' => '',
30 | 'oauth2_redirect_uri' => '',
31 |
32 | // The developer key, you get this at https://code.google.com/apis/console
33 | 'developer_key' => '',
34 |
35 | // Site name to show in the Google's OAuth 1 authentication screen.
36 | 'site_name' => 'www.example.org',
37 |
38 | // Which Authentication, Storage and HTTP IO classes to use.
39 | 'authClass' => 'Google_OAuth2',
40 | 'ioClass' => 'Google_CurlIO',
41 | 'cacheClass' => 'Google_FileCache',
42 |
43 | // Don't change these unless you're working against a special development or testing environment.
44 | 'basePath' => 'https://www.googleapis.com',
45 |
46 | // IO Class dependent configuration, you only have to configure the values
47 | // for the class that was configured as the ioClass above
48 | 'ioFileCache_directory' =>
49 | (function_exists('sys_get_temp_dir') ?
50 | sys_get_temp_dir() . '/Google_Client' :
51 | '/tmp/Google_Client'),
52 |
53 | // Definition of service specific values like scopes, oauth token URLs, etc
54 | 'services' => array(
55 | 'analytics' => array('scope' => 'https://www.googleapis.com/auth/analytics.readonly'),
56 | 'calendar' => array(
57 | 'scope' => array(
58 | "https://www.googleapis.com/auth/calendar",
59 | "https://www.googleapis.com/auth/calendar.readonly",
60 | )
61 | ),
62 | 'books' => array('scope' => 'https://www.googleapis.com/auth/books'),
63 | 'latitude' => array(
64 | 'scope' => array(
65 | 'https://www.googleapis.com/auth/latitude.all.best',
66 | 'https://www.googleapis.com/auth/latitude.all.city',
67 | )
68 | ),
69 | 'moderator' => array('scope' => 'https://www.googleapis.com/auth/moderator'),
70 | 'oauth2' => array(
71 | 'scope' => array(
72 | 'https://www.googleapis.com/auth/userinfo.profile',
73 | 'https://www.googleapis.com/auth/userinfo.email',
74 | )
75 | ),
76 | 'plus' => array('scope' => 'https://www.googleapis.com/auth/plus.me'),
77 | 'siteVerification' => array('scope' => 'https://www.googleapis.com/auth/siteverification'),
78 | 'tasks' => array('scope' => 'https://www.googleapis.com/auth/tasks'),
79 | 'urlshortener' => array('scope' => 'https://www.googleapis.com/auth/urlshortener')
80 | )
81 | );
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/external/OAuth.php:
--------------------------------------------------------------------------------
1 | key = $key;
15 | $this->secret = $secret;
16 | $this->callback_url = $callback_url;
17 | }
18 | }
19 |
20 | class apiClientOAuthToken {
21 | // access tokens and request tokens
22 | public $key;
23 | public $secret;
24 |
25 | /**
26 | * key = the token
27 | * secret = the token secret
28 | */
29 | function __construct($key, $secret) {
30 | $this->key = $key;
31 | $this->secret = $secret;
32 | }
33 |
34 | /**
35 | * generates the basic string serialization of a token that a server
36 | * would respond to request_token and access_token calls with
37 | */
38 | function to_string() {
39 | return "oauth_token=" . apiClientOAuthUtil::urlencodeRFC3986($this->key) .
40 | "&oauth_token_secret=" . apiClientOAuthUtil::urlencodeRFC3986($this->secret);
41 | }
42 |
43 | function __toString() {
44 | return $this->to_string();
45 | }
46 | }
47 |
48 | class apiClientOAuthSignatureMethod {
49 | public function check_signature(&$request, $consumer, $token, $signature) {
50 | $built = $this->build_signature($request, $consumer, $token);
51 | return $built == $signature;
52 | }
53 | }
54 |
55 | class apiClientOAuthSignatureMethod_HMAC_SHA1 extends apiClientOAuthSignatureMethod {
56 | function get_name() {
57 | return "HMAC-SHA1";
58 | }
59 |
60 | public function build_signature($request, $consumer, $token, $privKey=NULL) {
61 | $base_string = $request->get_signature_base_string();
62 | $request->base_string = $base_string;
63 |
64 | $key_parts = array(
65 | $consumer->secret,
66 | ($token) ? $token->secret : ""
67 | );
68 |
69 | $key_parts = array_map(array('apiClientOAuthUtil','urlencodeRFC3986'), $key_parts);
70 | $key = implode('&', $key_parts);
71 |
72 | return base64_encode( hash_hmac('sha1', $base_string, $key, true));
73 | }
74 | }
75 |
76 | class apiClientOAuthSignatureMethod_RSA_SHA1 extends apiClientOAuthSignatureMethod {
77 | public function get_name() {
78 | return "RSA-SHA1";
79 | }
80 |
81 | protected function fetch_public_cert(&$request) {
82 | // not implemented yet, ideas are:
83 | // (1) do a lookup in a table of trusted certs keyed off of consumer
84 | // (2) fetch via http using a url provided by the requester
85 | // (3) some sort of specific discovery code based on request
86 | //
87 | // either way should return a string representation of the certificate
88 | throw Exception("fetch_public_cert not implemented");
89 | }
90 |
91 | protected function fetch_private_cert($privKey) {//&$request) {
92 | // not implemented yet, ideas are:
93 | // (1) do a lookup in a table of trusted certs keyed off of consumer
94 | //
95 | // either way should return a string representation of the certificate
96 | throw Exception("fetch_private_cert not implemented");
97 | }
98 |
99 | public function build_signature(&$request, $consumer, $token, $privKey) {
100 | $base_string = $request->get_signature_base_string();
101 |
102 | // Fetch the private key cert based on the request
103 | //$cert = $this->fetch_private_cert($consumer->privKey);
104 |
105 | //Pull the private key ID from the certificate
106 | //$privatekeyid = openssl_get_privatekey($cert);
107 |
108 | // hacked in
109 | if ($privKey == '') {
110 | $fp = fopen($GLOBALS['PRIV_KEY_FILE'], "r");
111 | $privKey = fread($fp, 8192);
112 | fclose($fp);
113 | }
114 | $privatekeyid = openssl_get_privatekey($privKey);
115 |
116 | //Check the computer signature against the one passed in the query
117 | $ok = openssl_sign($base_string, $signature, $privatekeyid);
118 |
119 | //Release the key resource
120 | openssl_free_key($privatekeyid);
121 |
122 | return base64_encode($signature);
123 | }
124 |
125 | public function check_signature(&$request, $consumer, $token, $signature) {
126 | $decoded_sig = base64_decode($signature);
127 |
128 | $base_string = $request->get_signature_base_string();
129 |
130 | // Fetch the public key cert based on the request
131 | $cert = $this->fetch_public_cert($request);
132 |
133 | //Pull the public key ID from the certificate
134 | $publickeyid = openssl_get_publickey($cert);
135 |
136 | //Check the computer signature against the one passed in the query
137 | $ok = openssl_verify($base_string, $decoded_sig, $publickeyid);
138 |
139 | //Release the key resource
140 | openssl_free_key($publickeyid);
141 |
142 | return $ok == 1;
143 | }
144 | }
145 |
146 | class apiClientOAuthRequest {
147 | private $parameters;
148 | private $http_method;
149 | private $http_url;
150 | // for debug purposes
151 | public $base_string;
152 | public static $version = '1.0';
153 |
154 | function __construct($http_method, $http_url, $parameters=NULL) {
155 | @$parameters or $parameters = array();
156 | $this->parameters = $parameters;
157 | $this->http_method = $http_method;
158 | $this->http_url = $http_url;
159 | }
160 |
161 |
162 | /**
163 | * attempt to build up a request from what was passed to the server
164 | */
165 | public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) {
166 | $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on") ? 'http' : 'https';
167 | @$http_url or $http_url = $scheme . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
168 | @$http_method or $http_method = $_SERVER['REQUEST_METHOD'];
169 |
170 | $request_headers = apiClientOAuthRequest::get_headers();
171 |
172 | // let the library user override things however they'd like, if they know
173 | // which parameters to use then go for it, for example XMLRPC might want to
174 | // do this
175 | if ($parameters) {
176 | $req = new apiClientOAuthRequest($http_method, $http_url, $parameters);
177 | }
178 | // next check for the auth header, we need to do some extra stuff
179 | // if that is the case, namely suck in the parameters from GET or POST
180 | // so that we can include them in the signature
181 | else if (@substr($request_headers['Authorization'], 0, 5) == "OAuth") {
182 | $header_parameters = apiClientOAuthRequest::split_header($request_headers['Authorization']);
183 | if ($http_method == "GET") {
184 | $req_parameters = $_GET;
185 | }
186 | else if ($http_method = "POST") {
187 | $req_parameters = $_POST;
188 | }
189 | $parameters = array_merge($header_parameters, $req_parameters);
190 | $req = new apiClientOAuthRequest($http_method, $http_url, $parameters);
191 | }
192 | else if ($http_method == "GET") {
193 | $req = new apiClientOAuthRequest($http_method, $http_url, $_GET);
194 | }
195 | else if ($http_method == "POST") {
196 | $req = new apiClientOAuthRequest($http_method, $http_url, $_POST);
197 | }
198 | return $req;
199 | }
200 |
201 | /**
202 | * pretty much a helper function to set up the request
203 | */
204 | public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) {
205 | @$parameters or $parameters = array();
206 | $defaults = array("oauth_version" => apiClientOAuthRequest::$version,
207 | "oauth_nonce" => apiClientOAuthRequest::generate_nonce(),
208 | "oauth_timestamp" => apiClientOAuthRequest::generate_timestamp(),
209 | "oauth_consumer_key" => $consumer->key);
210 | $parameters = array_merge($defaults, $parameters);
211 |
212 | if ($token) {
213 | $parameters['oauth_token'] = $token->key;
214 | }
215 |
216 | // oauth v1.0a
217 | /*if (isset($_REQUEST['oauth_verifier'])) {
218 | $parameters['oauth_verifier'] = $_REQUEST['oauth_verifier'];
219 | }*/
220 |
221 |
222 | return new apiClientOAuthRequest($http_method, $http_url, $parameters);
223 | }
224 |
225 | public function set_parameter($name, $value) {
226 | $this->parameters[$name] = $value;
227 | }
228 |
229 | public function get_parameter($name) {
230 | return $this->parameters[$name];
231 | }
232 |
233 | public function get_parameters() {
234 | return $this->parameters;
235 | }
236 |
237 | /**
238 | * Returns the normalized parameters of the request
239 | *
240 | * This will be all (except oauth_signature) parameters,
241 | * sorted first by key, and if duplicate keys, then by
242 | * value.
243 | *
244 | * The returned string will be all the key=value pairs
245 | * concated by &.
246 | *
247 | * @return string
248 | */
249 | public function get_signable_parameters() {
250 | // Grab all parameters
251 | $params = $this->parameters;
252 |
253 | // Remove oauth_signature if present
254 | if (isset($params['oauth_signature'])) {
255 | unset($params['oauth_signature']);
256 | }
257 |
258 | // Urlencode both keys and values
259 | $keys = array_map(array('apiClientOAuthUtil', 'urlencodeRFC3986'), array_keys($params));
260 | $values = array_map(array('apiClientOAuthUtil', 'urlencodeRFC3986'), array_values($params));
261 | $params = array_combine($keys, $values);
262 |
263 | // Sort by keys (natsort)
264 | uksort($params, 'strnatcmp');
265 |
266 | if(isset($params['title']) && isset($params['title-exact'])) {
267 | $temp = $params['title-exact'];
268 | $title = $params['title'];
269 |
270 | unset($params['title']);
271 | unset($params['title-exact']);
272 |
273 | $params['title-exact'] = $temp;
274 | $params['title'] = $title;
275 | }
276 |
277 | // Generate key=value pairs
278 | $pairs = array();
279 | foreach ($params as $key=>$value ) {
280 | if (is_array($value)) {
281 | // If the value is an array, it's because there are multiple
282 | // with the same key, sort them, then add all the pairs
283 | natsort($value);
284 | foreach ($value as $v2) {
285 | $pairs[] = $key . '=' . $v2;
286 | }
287 | } else {
288 | $pairs[] = $key . '=' . $value;
289 | }
290 | }
291 |
292 | // Return the pairs, concated with &
293 | return implode('&', $pairs);
294 | }
295 |
296 | /**
297 | * Returns the base string of this request
298 | *
299 | * The base string defined as the method, the url
300 | * and the parameters (normalized), each urlencoded
301 | * and the concated with &.
302 | */
303 | public function get_signature_base_string() {
304 | $parts = array(
305 | $this->get_normalized_http_method(),
306 | $this->get_normalized_http_url(),
307 | $this->get_signable_parameters()
308 | );
309 |
310 | $parts = array_map(array('apiClientOAuthUtil', 'urlencodeRFC3986'), $parts);
311 |
312 | return implode('&', $parts);
313 | }
314 |
315 | /**
316 | * just uppercases the http method
317 | */
318 | public function get_normalized_http_method() {
319 | return strtoupper($this->http_method);
320 | }
321 |
322 | /**
323 | * parses the url and rebuilds it to be
324 | * scheme://host/path
325 | */
326 | public function get_normalized_http_url() {
327 | $parts = parse_url($this->http_url);
328 |
329 | // FIXME: port should handle according to http://groups.google.com/group/oauth/browse_thread/thread/1b203a51d9590226
330 | $port = (isset($parts['port']) && $parts['port'] != '80') ? ':' . $parts['port'] : '';
331 | $path = (isset($parts['path'])) ? $parts['path'] : '';
332 |
333 | return $parts['scheme'] . '://' . $parts['host'] . $port . $path;
334 | }
335 |
336 | /**
337 | * builds a url usable for a GET request
338 | */
339 | public function to_url() {
340 | $out = $this->get_normalized_http_url() . "?";
341 | $out .= $this->to_postdata();
342 | return $out;
343 | }
344 |
345 | /**
346 | * builds the data one would send in a POST request
347 | */
348 | public function to_postdata() {
349 | $total = array();
350 | foreach ($this->parameters as $k => $v) {
351 | $total[] = apiClientOAuthUtil::urlencodeRFC3986($k) . "=" . apiClientOAuthUtil::urlencodeRFC3986($v);
352 | }
353 | $out = implode("&", $total);
354 | return $out;
355 | }
356 |
357 | /**
358 | * builds the Authorization: header
359 | */
360 | public function to_header() {
361 | $out ='Authorization: OAuth ';
362 | $total = array();
363 | foreach ($this->parameters as $k => $v) {
364 | if (substr($k, 0, 5) != "oauth") continue;
365 | $out .= apiClientOAuthUtil::urlencodeRFC3986($k) . '="' . apiClientOAuthUtil::urlencodeRFC3986($v) . '", ';
366 | }
367 | $out = substr_replace($out, '', strlen($out) - 2);
368 | return $out;
369 | }
370 |
371 | public function __toString() {
372 | return $this->to_url();
373 | }
374 |
375 |
376 | public function sign_request($signature_method, $consumer, $token, $privKey=NULL) {
377 | $this->set_parameter("oauth_signature_method", $signature_method->get_name());
378 | $signature = $this->build_signature($signature_method, $consumer, $token, $privKey);
379 | $this->set_parameter("oauth_signature", $signature);
380 | }
381 |
382 | public function build_signature($signature_method, $consumer, $token, $privKey=NULL) {
383 | $signature = $signature_method->build_signature($this, $consumer, $token, $privKey);
384 | return $signature;
385 | }
386 |
387 | /**
388 | * util function: current timestamp
389 | */
390 | private static function generate_timestamp() {
391 | return time();
392 | }
393 |
394 | /**
395 | * util function: current nonce
396 | */
397 | private static function generate_nonce() {
398 | $mt = microtime();
399 | $rand = mt_rand();
400 |
401 | return md5($mt . $rand); // md5s look nicer than numbers
402 | }
403 |
404 | /**
405 | * util function for turning the Authorization: header into
406 | * parameters, has to do some unescaping
407 | */
408 | private static function split_header($header) {
409 | // this should be a regex
410 | // error cases: commas in parameter values
411 | $parts = explode(",", $header);
412 | $out = array();
413 | foreach ($parts as $param) {
414 | $param = ltrim($param);
415 | // skip the "realm" param, nobody ever uses it anyway
416 | if (substr($param, 0, 5) != "oauth") continue;
417 |
418 | $param_parts = explode("=", $param);
419 |
420 | // rawurldecode() used because urldecode() will turn a "+" in the
421 | // value into a space
422 | $out[$param_parts[0]] = rawurldecode(substr($param_parts[1], 1, -1));
423 | }
424 | return $out;
425 | }
426 |
427 | /**
428 | * helper to try to sort out headers for people who aren't running apache
429 | */
430 | private static function get_headers() {
431 | if (function_exists('apache_request_headers')) {
432 | // we need this to get the actual Authorization: header
433 | // because apache tends to tell us it doesn't exist
434 | return apache_request_headers();
435 | }
436 | // otherwise we don't have apache and are just going to have to hope
437 | // that $_SERVER actually contains what we need
438 | $out = array();
439 | foreach ($_SERVER as $key => $value) {
440 | if (substr($key, 0, 5) == "HTTP_") {
441 | // this is chaos, basically it is just there to capitalize the first
442 | // letter of every word that is not an initial HTTP and strip HTTP
443 | // code from przemek
444 | $key = str_replace(" ", "-", ucwords(strtolower(str_replace("_", " ", substr($key, 5)))));
445 | $out[$key] = $value;
446 | }
447 | }
448 | return $out;
449 | }
450 | }
451 |
452 | class apiClientOAuthDataStore {
453 | function lookup_consumer($consumer_key) {
454 | // implement me
455 | }
456 |
457 | function lookup_token($consumer, $token_type, $token) {
458 | // implement me
459 | }
460 |
461 | function lookup_nonce($consumer, $token, $nonce, $timestamp) {
462 | // implement me
463 | }
464 |
465 | function fetch_request_token($consumer) {
466 | // return a new token attached to this consumer
467 | }
468 |
469 | function fetch_access_token($token, $consumer) {
470 | // return a new access token attached to this consumer
471 | // for the user associated with this token if the request token
472 | // is authorized
473 | // should also invalidate the request token
474 | }
475 |
476 | }
477 |
478 | class apiClientOAuthUtil {
479 | public static function urlencodeRFC3986($string) {
480 | return str_replace('%7E', '~', rawurlencode($string));
481 | }
482 |
483 | public static function urldecodeRFC3986($string) {
484 | return rawurldecode($string);
485 | }
486 | }
487 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/external/URITemplateParser.php:
--------------------------------------------------------------------------------
1 | template = $template;
48 | }
49 |
50 | public function expand($data) {
51 | // Modification to make this a bit more performant (since gettype is very slow)
52 | if (! is_array($data)) {
53 | $data = (array)$data;
54 | }
55 | /*
56 | // Original code, which uses a slow gettype() statement, kept in place for if the assumption that is_array always works here is incorrect
57 | switch (gettype($data)) {
58 | case "boolean":
59 | case "integer":
60 | case "double":
61 | case "string":
62 | case "object":
63 | $data = (array)$data;
64 | break;
65 | }
66 | */
67 |
68 | // Resolve template vars
69 | preg_match_all('/\{([^\}]*)\}/', $this->template, $em);
70 |
71 | foreach ($em[1] as $i => $bare_expression) {
72 | preg_match('/^([\+\;\?\/\.]{1})?(.*)$/', $bare_expression, $lm);
73 | $exp = new StdClass();
74 | $exp->expression = $em[0][$i];
75 | $exp->operator = $lm[1];
76 | $exp->variable_list = $lm[2];
77 | $exp->varspecs = explode(',', $exp->variable_list);
78 | $exp->vars = array();
79 | foreach ($exp->varspecs as $varspec) {
80 | preg_match('/^([a-zA-Z0-9_]+)([\*\+]{1})?([\:\^][0-9-]+)?(\=[^,]+)?$/', $varspec, $vm);
81 | $var = new StdClass();
82 | $var->name = $vm[1];
83 | $var->modifier = isset($vm[2]) && $vm[2] ? $vm[2] : null;
84 | $var->modifier = isset($vm[3]) && $vm[3] ? $vm[3] : $var->modifier;
85 | $var->default = isset($vm[4]) ? substr($vm[4], 1) : null;
86 | $exp->vars[] = $var;
87 | }
88 |
89 | // Add processing flags
90 | $exp->reserved = false;
91 | $exp->prefix = '';
92 | $exp->delimiter = ',';
93 | switch ($exp->operator) {
94 | case '+':
95 | $exp->reserved = 'true';
96 | break;
97 | case ';':
98 | $exp->prefix = ';';
99 | $exp->delimiter = ';';
100 | break;
101 | case '?':
102 | $exp->prefix = '?';
103 | $exp->delimiter = '&';
104 | break;
105 | case '/':
106 | $exp->prefix = '/';
107 | $exp->delimiter = '/';
108 | break;
109 | case '.':
110 | $exp->prefix = '.';
111 | $exp->delimiter = '.';
112 | break;
113 | }
114 | $expressions[] = $exp;
115 | }
116 |
117 | // Expansion
118 | $this->expansion = $this->template;
119 |
120 | foreach ($expressions as $exp) {
121 | $part = $exp->prefix;
122 | $exp->one_var_defined = false;
123 | foreach ($exp->vars as $var) {
124 | $val = '';
125 | if ($exp->one_var_defined && isset($data[$var->name])) {
126 | $part .= $exp->delimiter;
127 | }
128 | // Variable present
129 | if (isset($data[$var->name])) {
130 | $exp->one_var_defined = true;
131 | $var->data = $data[$var->name];
132 |
133 | $val = self::val_from_var($var, $exp);
134 |
135 | // Variable missing
136 | } else {
137 | if ($var->default) {
138 | $exp->one_var_defined = true;
139 | $val = $var->default;
140 | }
141 | }
142 | $part .= $val;
143 | }
144 | if (! $exp->one_var_defined) $part = '';
145 | $this->expansion = str_replace($exp->expression, $part, $this->expansion);
146 | }
147 |
148 | return $this->expansion;
149 | }
150 |
151 | private function val_from_var($var, $exp) {
152 | $val = '';
153 | if (is_array($var->data)) {
154 | $i = 0;
155 | if ($exp->operator == '?' && ! $var->modifier) {
156 | $val .= $var->name . '=';
157 | }
158 | foreach ($var->data as $k => $v) {
159 | $del = $var->modifier ? $exp->delimiter : ',';
160 | $ek = rawurlencode($k);
161 | $ev = rawurlencode($v);
162 |
163 | // Array
164 | if ($k !== $i) {
165 | if ($var->modifier == '+') {
166 | $val .= $var->name . '.';
167 | }
168 | if ($exp->operator == '?' && $var->modifier || $exp->operator == ';' && $var->modifier == '*' || $exp->operator == ';' && $var->modifier == '+') {
169 | $val .= $ek . '=';
170 | } else {
171 | $val .= $ek . $del;
172 | }
173 |
174 | // List
175 | } else {
176 | if ($var->modifier == '+') {
177 | if ($exp->operator == ';' && $var->modifier == '*' || $exp->operator == ';' && $var->modifier == '+' || $exp->operator == '?' && $var->modifier == '+') {
178 | $val .= $var->name . '=';
179 | } else {
180 | $val .= $var->name . '.';
181 | }
182 | }
183 | }
184 | $val .= $ev . $del;
185 | $i ++;
186 | }
187 | $val = trim($val, $del);
188 |
189 | // Strings, numbers, etc.
190 | } else {
191 | if ($exp->operator == '?') {
192 | $val = $var->name . (isset($var->data) ? '=' : '');
193 | } else if ($exp->operator == ';') {
194 | $val = $var->name . ($var->data ? '=' : '');
195 | }
196 | $val .= rawurlencode($var->data);
197 | if ($exp->operator == '+') {
198 | $val = str_replace(self::$reserved_pct, self::$reserved, $val);
199 | }
200 | }
201 | return $val;
202 | }
203 |
204 | public function match($uri) {}
205 |
206 | public function __toString() {
207 | return $this->template;
208 | }
209 | }
210 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/io/Google_CacheParser.php:
--------------------------------------------------------------------------------
1 |
21 | */
22 | class Google_CacheParser {
23 | public static $CACHEABLE_HTTP_METHODS = array('GET', 'HEAD');
24 | public static $CACHEABLE_STATUS_CODES = array('200', '203', '300', '301');
25 |
26 | private function __construct() {}
27 |
28 | /**
29 | * Check if an HTTP request can be cached by a private local cache.
30 | *
31 | * @static
32 | * @param Google_HttpRequest $resp
33 | * @return bool True if the request is cacheable.
34 | * False if the request is uncacheable.
35 | */
36 | public static function isRequestCacheable (Google_HttpRequest $resp) {
37 | $method = $resp->getRequestMethod();
38 | if (! in_array($method, self::$CACHEABLE_HTTP_METHODS)) {
39 | return false;
40 | }
41 |
42 | // Don't cache authorized requests/responses.
43 | // [rfc2616-14.8] When a shared cache receives a request containing an
44 | // Authorization field, it MUST NOT return the corresponding response
45 | // as a reply to any other request...
46 | if ($resp->getRequestHeader("authorization")) {
47 | return false;
48 | }
49 |
50 | return true;
51 | }
52 |
53 | /**
54 | * Check if an HTTP response can be cached by a private local cache.
55 | *
56 | * @static
57 | * @param Google_HttpRequest $resp
58 | * @return bool True if the response is cacheable.
59 | * False if the response is un-cacheable.
60 | */
61 | public static function isResponseCacheable (Google_HttpRequest $resp) {
62 | // First, check if the HTTP request was cacheable before inspecting the
63 | // HTTP response.
64 | if (false == self::isRequestCacheable($resp)) {
65 | return false;
66 | }
67 |
68 | $code = $resp->getResponseHttpCode();
69 | if (! in_array($code, self::$CACHEABLE_STATUS_CODES)) {
70 | return false;
71 | }
72 |
73 | // The resource is uncacheable if the resource is already expired and
74 | // the resource doesn't have an ETag for revalidation.
75 | $etag = $resp->getResponseHeader("etag");
76 | if (self::isExpired($resp) && $etag == false) {
77 | return false;
78 | }
79 |
80 | // [rfc2616-14.9.2] If [no-store is] sent in a response, a cache MUST NOT
81 | // store any part of either this response or the request that elicited it.
82 | $cacheControl = $resp->getParsedCacheControl();
83 | if (isset($cacheControl['no-store'])) {
84 | return false;
85 | }
86 |
87 | // Pragma: no-cache is an http request directive, but is occasionally
88 | // used as a response header incorrectly.
89 | $pragma = $resp->getResponseHeader('pragma');
90 | if ($pragma == 'no-cache' || strpos($pragma, 'no-cache') !== false) {
91 | return false;
92 | }
93 |
94 | // [rfc2616-14.44] Vary: * is extremely difficult to cache. "It implies that
95 | // a cache cannot determine from the request headers of a subsequent request
96 | // whether this response is the appropriate representation."
97 | // Given this, we deem responses with the Vary header as uncacheable.
98 | $vary = $resp->getResponseHeader('vary');
99 | if ($vary) {
100 | return false;
101 | }
102 |
103 | return true;
104 | }
105 |
106 | /**
107 | * @static
108 | * @param Google_HttpRequest $resp
109 | * @return bool True if the HTTP response is considered to be expired.
110 | * False if it is considered to be fresh.
111 | */
112 | public static function isExpired(Google_HttpRequest $resp) {
113 | // HTTP/1.1 clients and caches MUST treat other invalid date formats,
114 | // especially including the value “0”, as in the past.
115 | $parsedExpires = false;
116 | $responseHeaders = $resp->getResponseHeaders();
117 | if (isset($responseHeaders['expires'])) {
118 | $rawExpires = $responseHeaders['expires'];
119 | // Check for a malformed expires header first.
120 | if (empty($rawExpires) || (is_numeric($rawExpires) && $rawExpires <= 0)) {
121 | return true;
122 | }
123 |
124 | // See if we can parse the expires header.
125 | $parsedExpires = strtotime($rawExpires);
126 | if (false == $parsedExpires || $parsedExpires <= 0) {
127 | return true;
128 | }
129 | }
130 |
131 | // Calculate the freshness of an http response.
132 | $freshnessLifetime = false;
133 | $cacheControl = $resp->getParsedCacheControl();
134 | if (isset($cacheControl['max-age'])) {
135 | $freshnessLifetime = $cacheControl['max-age'];
136 | }
137 |
138 | $rawDate = $resp->getResponseHeader('date');
139 | $parsedDate = strtotime($rawDate);
140 |
141 | if (empty($rawDate) || false == $parsedDate) {
142 | $parsedDate = time();
143 | }
144 | if (false == $freshnessLifetime && isset($responseHeaders['expires'])) {
145 | $freshnessLifetime = $parsedExpires - $parsedDate;
146 | }
147 |
148 | if (false == $freshnessLifetime) {
149 | return true;
150 | }
151 |
152 | // Calculate the age of an http response.
153 | $age = max(0, time() - $parsedDate);
154 | if (isset($responseHeaders['age'])) {
155 | $age = max($age, strtotime($responseHeaders['age']));
156 | }
157 |
158 | return $freshnessLifetime <= $age;
159 | }
160 |
161 | /**
162 | * Determine if a cache entry should be revalidated with by the origin.
163 | *
164 | * @param Google_HttpRequest $response
165 | * @return bool True if the entry is expired, else return false.
166 | */
167 | public static function mustRevalidate(Google_HttpRequest $response) {
168 | // [13.3] When a cache has a stale entry that it would like to use as a
169 | // response to a client's request, it first has to check with the origin
170 | // server to see if its cached entry is still usable.
171 | return self::isExpired($response);
172 | }
173 | }
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/io/Google_CurlIO.php:
--------------------------------------------------------------------------------
1 |
22 | * @author Chirag Shah
23 | */
24 |
25 | require_once 'Google_CacheParser.php';
26 |
27 | class Google_CurlIO implements Google_IO {
28 | const CONNECTION_ESTABLISHED = "HTTP/1.0 200 Connection established\r\n\r\n";
29 | const FORM_URLENCODED = 'application/x-www-form-urlencoded';
30 |
31 | private static $ENTITY_HTTP_METHODS = array("POST" => null, "PUT" => null);
32 | private static $HOP_BY_HOP = array(
33 | 'connection', 'keep-alive', 'proxy-authenticate', 'proxy-authorization',
34 | 'te', 'trailers', 'transfer-encoding', 'upgrade');
35 |
36 | private $curlParams = array (
37 | CURLOPT_RETURNTRANSFER => true,
38 | CURLOPT_FOLLOWLOCATION => 0,
39 | CURLOPT_FAILONERROR => false,
40 | CURLOPT_SSL_VERIFYPEER => true,
41 | CURLOPT_HEADER => true,
42 | CURLOPT_VERBOSE => false,
43 | );
44 |
45 | /**
46 | * Perform an authenticated / signed apiHttpRequest.
47 | * This function takes the apiHttpRequest, calls apiAuth->sign on it
48 | * (which can modify the request in what ever way fits the auth mechanism)
49 | * and then calls apiCurlIO::makeRequest on the signed request
50 | *
51 | * @param Google_HttpRequest $request
52 | * @return Google_HttpRequest The resulting HTTP response including the
53 | * responseHttpCode, responseHeaders and responseBody.
54 | */
55 | public function authenticatedRequest(Google_HttpRequest $request) {
56 | $request = Google_Client::$auth->sign($request);
57 | return $this->makeRequest($request);
58 | }
59 |
60 | /**
61 | * Execute a apiHttpRequest
62 | *
63 | * @param Google_HttpRequest $request the http request to be executed
64 | * @return Google_HttpRequest http request with the response http code, response
65 | * headers and response body filled in
66 | * @throws Google_IOException on curl or IO error
67 | */
68 | public function makeRequest(Google_HttpRequest $request) {
69 | // First, check to see if we have a valid cached version.
70 | $cached = $this->getCachedRequest($request);
71 | if ($cached !== false) {
72 | if (Google_CacheParser::mustRevalidate($cached)) {
73 | $addHeaders = array();
74 | if ($cached->getResponseHeader('etag')) {
75 | // [13.3.4] If an entity tag has been provided by the origin server,
76 | // we must use that entity tag in any cache-conditional request.
77 | $addHeaders['If-None-Match'] = $cached->getResponseHeader('etag');
78 | } elseif ($cached->getResponseHeader('date')) {
79 | $addHeaders['If-Modified-Since'] = $cached->getResponseHeader('date');
80 | }
81 |
82 | $request->setRequestHeaders($addHeaders);
83 | } else {
84 | // No need to revalidate the request, return it directly
85 | return $cached;
86 | }
87 | }
88 |
89 | if (array_key_exists($request->getRequestMethod(),
90 | self::$ENTITY_HTTP_METHODS)) {
91 | $request = $this->processEntityRequest($request);
92 | }
93 |
94 | $ch = curl_init();
95 | curl_setopt_array($ch, $this->curlParams);
96 | curl_setopt($ch, CURLOPT_URL, $request->getUrl());
97 | if ($request->getPostBody()) {
98 | curl_setopt($ch, CURLOPT_POSTFIELDS, $request->getPostBody());
99 | }
100 |
101 | $requestHeaders = $request->getRequestHeaders();
102 | if ($requestHeaders && is_array($requestHeaders)) {
103 | $parsed = array();
104 | foreach ($requestHeaders as $k => $v) {
105 | $parsed[] = "$k: $v";
106 | }
107 | curl_setopt($ch, CURLOPT_HTTPHEADER, $parsed);
108 | }
109 |
110 | curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $request->getRequestMethod());
111 | curl_setopt($ch, CURLOPT_USERAGENT, $request->getUserAgent());
112 | $respData = curl_exec($ch);
113 |
114 | // Retry if certificates are missing.
115 | if (curl_errno($ch) == CURLE_SSL_CACERT) {
116 | error_log('SSL certificate problem, verify that the CA cert is OK.'
117 | . ' Retrying with the CA cert bundle from google-api-php-client.');
118 | curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacerts.pem');
119 | $respData = curl_exec($ch);
120 | }
121 |
122 | $respHeaderSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
123 | $respHttpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
124 | $curlErrorNum = curl_errno($ch);
125 | $curlError = curl_error($ch);
126 | curl_close($ch);
127 | if ($curlErrorNum != CURLE_OK) {
128 | throw new Google_IOException("HTTP Error: ($respHttpCode) $curlError");
129 | }
130 |
131 | // Parse out the raw response into usable bits
132 | list($responseHeaders, $responseBody) =
133 | self::parseHttpResponse($respData, $respHeaderSize);
134 |
135 | if ($respHttpCode == 304 && $cached) {
136 | // If the server responded NOT_MODIFIED, return the cached request.
137 | if (isset($responseHeaders['connection'])) {
138 | $hopByHop = array_merge(
139 | self::$HOP_BY_HOP,
140 | explode(',', $responseHeaders['connection'])
141 | );
142 |
143 | $endToEnd = array();
144 | foreach($hopByHop as $key) {
145 | if (isset($responseHeaders[$key])) {
146 | $endToEnd[$key] = $responseHeaders[$key];
147 | }
148 | }
149 | $cached->setResponseHeaders($endToEnd);
150 | }
151 | return $cached;
152 | }
153 |
154 | // Fill in the apiHttpRequest with the response values
155 | $request->setResponseHttpCode($respHttpCode);
156 | $request->setResponseHeaders($responseHeaders);
157 | $request->setResponseBody($responseBody);
158 | // Store the request in cache (the function checks to see if the request
159 | // can actually be cached)
160 | $this->setCachedRequest($request);
161 | // And finally return it
162 | return $request;
163 | }
164 |
165 | /**
166 | * @visible for testing.
167 | * Cache the response to an HTTP request if it is cacheable.
168 | * @param Google_HttpRequest $request
169 | * @return bool Returns true if the insertion was successful.
170 | * Otherwise, return false.
171 | */
172 | public function setCachedRequest(Google_HttpRequest $request) {
173 | // Determine if the request is cacheable.
174 | if (Google_CacheParser::isResponseCacheable($request)) {
175 | Google_Client::$cache->set($request->getCacheKey(), $request);
176 | return true;
177 | }
178 |
179 | return false;
180 | }
181 |
182 | /**
183 | * @visible for testing.
184 | * @param Google_HttpRequest $request
185 | * @return Google_HttpRequest|bool Returns the cached object or
186 | * false if the operation was unsuccessful.
187 | */
188 | public function getCachedRequest(Google_HttpRequest $request) {
189 | if (false == Google_CacheParser::isRequestCacheable($request)) {
190 | false;
191 | }
192 |
193 | return Google_Client::$cache->get($request->getCacheKey());
194 | }
195 |
196 | /**
197 | * @param $respData
198 | * @param $headerSize
199 | * @return array
200 | */
201 | public static function parseHttpResponse($respData, $headerSize) {
202 | if (stripos($respData, self::CONNECTION_ESTABLISHED) !== false) {
203 | $respData = str_ireplace(self::CONNECTION_ESTABLISHED, '', $respData);
204 | }
205 |
206 | if ($headerSize) {
207 | $responseBody = substr($respData, $headerSize);
208 | $responseHeaders = substr($respData, 0, $headerSize);
209 | } else {
210 | list($responseHeaders, $responseBody) = explode("\r\n\r\n", $respData, 2);
211 | }
212 |
213 | $responseHeaders = self::parseResponseHeaders($responseHeaders);
214 | return array($responseHeaders, $responseBody);
215 | }
216 |
217 | public static function parseResponseHeaders($rawHeaders) {
218 | $responseHeaders = array();
219 |
220 | $responseHeaderLines = explode("\r\n", $rawHeaders);
221 | foreach ($responseHeaderLines as $headerLine) {
222 | if ($headerLine && strpos($headerLine, ':') !== false) {
223 | list($header, $value) = explode(': ', $headerLine, 2);
224 | $header = strtolower($header);
225 | if (isset($responseHeaders[$header])) {
226 | $responseHeaders[$header] .= "\n" . $value;
227 | } else {
228 | $responseHeaders[$header] = $value;
229 | }
230 | }
231 | }
232 | return $responseHeaders;
233 | }
234 |
235 | /**
236 | * @visible for testing
237 | * Process an http request that contains an enclosed entity.
238 | * @param Google_HttpRequest $request
239 | * @return Google_HttpRequest Processed request with the enclosed entity.
240 | */
241 | public function processEntityRequest(Google_HttpRequest $request) {
242 | $postBody = $request->getPostBody();
243 | $contentType = $request->getRequestHeader("content-type");
244 |
245 | // Set the default content-type as application/x-www-form-urlencoded.
246 | if (false == $contentType) {
247 | $contentType = self::FORM_URLENCODED;
248 | $request->setRequestHeaders(array('content-type' => $contentType));
249 | }
250 |
251 | // Force the payload to match the content-type asserted in the header.
252 | if ($contentType == self::FORM_URLENCODED && is_array($postBody)) {
253 | $postBody = http_build_query($postBody, '', '&');
254 | $request->setPostBody($postBody);
255 | }
256 |
257 | // Make sure the content-length header is set.
258 | if (!$postBody || is_string($postBody)) {
259 | $postsLength = strlen($postBody);
260 | $request->setRequestHeaders(array('content-length' => $postsLength));
261 | }
262 |
263 | return $request;
264 | }
265 |
266 | /**
267 | * Set options that update cURL's default behavior.
268 | * The list of accepted options are:
269 | * {@link http://php.net/manual/en/function.curl-setopt.php]
270 | *
271 | * @param array $optCurlParams Multiple options used by a cURL session.
272 | */
273 | public function setOptions($optCurlParams) {
274 | foreach ($optCurlParams as $key => $val) {
275 | $this->curlParams[$key] = $val;
276 | }
277 | }
278 | }
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/io/Google_HttpRequest.php:
--------------------------------------------------------------------------------
1 |
23 | * @author Chirag Shah
24 | *
25 | */
26 | class Google_HttpRequest {
27 | const USER_AGENT_SUFFIX = "google-api-php-client/0.6.0";
28 | private $batchHeaders = array(
29 | 'Content-Type' => 'application/http',
30 | 'Content-Transfer-Encoding' => 'binary',
31 | 'MIME-Version' => '1.0',
32 | 'Content-Length' => ''
33 | );
34 |
35 | protected $url;
36 | protected $requestMethod;
37 | protected $requestHeaders;
38 | protected $postBody;
39 | protected $userAgent;
40 |
41 | protected $responseHttpCode;
42 | protected $responseHeaders;
43 | protected $responseBody;
44 |
45 | public $accessKey;
46 |
47 | public function __construct($url, $method = 'GET', $headers = array(), $postBody = null) {
48 | $this->setUrl($url);
49 | $this->setRequestMethod($method);
50 | $this->setRequestHeaders($headers);
51 | $this->setPostBody($postBody);
52 |
53 | global $apiConfig;
54 | if (empty($apiConfig['application_name'])) {
55 | $this->userAgent = self::USER_AGENT_SUFFIX;
56 | } else {
57 | $this->userAgent = $apiConfig['application_name'] . " " . self::USER_AGENT_SUFFIX;
58 | }
59 | }
60 |
61 | /**
62 | * Misc function that returns the base url component of the $url
63 | * used by the OAuth signing class to calculate the base string
64 | * @return string The base url component of the $url.
65 | * @see http://oauth.net/core/1.0a/#anchor13
66 | */
67 | public function getBaseUrl() {
68 | if ($pos = strpos($this->url, '?')) {
69 | return substr($this->url, 0, $pos);
70 | }
71 | return $this->url;
72 | }
73 |
74 | /**
75 | * Misc function that returns an array of the query parameters of the current
76 | * url used by the OAuth signing class to calculate the signature
77 | * @return array Query parameters in the query string.
78 | */
79 | public function getQueryParams() {
80 | if ($pos = strpos($this->url, '?')) {
81 | $queryStr = substr($this->url, $pos + 1);
82 | $params = array();
83 | parse_str($queryStr, $params);
84 | return $params;
85 | }
86 | return array();
87 | }
88 |
89 | /**
90 | * @return string HTTP Response Code.
91 | */
92 | public function getResponseHttpCode() {
93 | return (int) $this->responseHttpCode;
94 | }
95 |
96 | /**
97 | * @param int $responseHttpCode HTTP Response Code.
98 | */
99 | public function setResponseHttpCode($responseHttpCode) {
100 | $this->responseHttpCode = $responseHttpCode;
101 | }
102 |
103 | /**
104 | * @return $responseHeaders (array) HTTP Response Headers.
105 | */
106 | public function getResponseHeaders() {
107 | return $this->responseHeaders;
108 | }
109 |
110 | /**
111 | * @return string HTTP Response Body
112 | */
113 | public function getResponseBody() {
114 | return $this->responseBody;
115 | }
116 |
117 | /**
118 | * @param array $headers The HTTP response headers
119 | * to be normalized.
120 | */
121 | public function setResponseHeaders($headers) {
122 | $headers = Google_Utils::normalize($headers);
123 | if ($this->responseHeaders) {
124 | $headers = array_merge($this->responseHeaders, $headers);
125 | }
126 |
127 | $this->responseHeaders = $headers;
128 | }
129 |
130 | /**
131 | * @param string $key
132 | * @return array|boolean Returns the requested HTTP header or
133 | * false if unavailable.
134 | */
135 | public function getResponseHeader($key) {
136 | return isset($this->responseHeaders[$key])
137 | ? $this->responseHeaders[$key]
138 | : false;
139 | }
140 |
141 | /**
142 | * @param string $responseBody The HTTP response body.
143 | */
144 | public function setResponseBody($responseBody) {
145 | $this->responseBody = $responseBody;
146 | }
147 |
148 | /**
149 | * @return string $url The request URL.
150 | */
151 |
152 | public function getUrl() {
153 | return $this->url;
154 | }
155 |
156 | /**
157 | * @return string $method HTTP Request Method.
158 | */
159 | public function getRequestMethod() {
160 | return $this->requestMethod;
161 | }
162 |
163 | /**
164 | * @return array $headers HTTP Request Headers.
165 | */
166 | public function getRequestHeaders() {
167 | return $this->requestHeaders;
168 | }
169 |
170 | /**
171 | * @param string $key
172 | * @return array|boolean Returns the requested HTTP header or
173 | * false if unavailable.
174 | */
175 | public function getRequestHeader($key) {
176 | return isset($this->requestHeaders[$key])
177 | ? $this->requestHeaders[$key]
178 | : false;
179 | }
180 |
181 | /**
182 | * @return string $postBody HTTP Request Body.
183 | */
184 | public function getPostBody() {
185 | return $this->postBody;
186 | }
187 |
188 | /**
189 | * @param string $url the url to set
190 | */
191 | public function setUrl($url) {
192 | if (substr($url, 0, 4) == 'http') {
193 | $this->url = $url;
194 | } else {
195 | // Force the path become relative.
196 | if (substr($url, 0, 1) !== '/') {
197 | $url = '/' . $url;
198 | }
199 | global $apiConfig;
200 | $this->url = $apiConfig['basePath'] . $url;
201 | }
202 | }
203 |
204 | /**
205 | * @param string $method Set he HTTP Method and normalize
206 | * it to upper-case, as required by HTTP.
207 | *
208 | */
209 | public function setRequestMethod($method) {
210 | $this->requestMethod = strtoupper($method);
211 | }
212 |
213 | /**
214 | * @param array $headers The HTTP request headers
215 | * to be set and normalized.
216 | */
217 | public function setRequestHeaders($headers) {
218 | $headers = Google_Utils::normalize($headers);
219 | if ($this->requestHeaders) {
220 | $headers = array_merge($this->requestHeaders, $headers);
221 | }
222 | $this->requestHeaders = $headers;
223 | }
224 |
225 | /**
226 | * @param string $postBody the postBody to set
227 | */
228 | public function setPostBody($postBody) {
229 | $this->postBody = $postBody;
230 | }
231 |
232 | /**
233 | * Set the User-Agent Header.
234 | * @param string $userAgent The User-Agent.
235 | */
236 | public function setUserAgent($userAgent) {
237 | $this->userAgent = $userAgent;
238 | }
239 |
240 | /**
241 | * @return string The User-Agent.
242 | */
243 | public function getUserAgent() {
244 | return $this->userAgent;
245 | }
246 |
247 | /**
248 | * Returns a cache key depending on if this was an OAuth signed request
249 | * in which case it will use the non-signed url and access key to make this
250 | * cache key unique per authenticated user, else use the plain request url
251 | * @return string The md5 hash of the request cache key.
252 | */
253 | public function getCacheKey() {
254 | $key = $this->getUrl();
255 |
256 | if (isset($this->accessKey)) {
257 | $key .= $this->accessKey;
258 | }
259 |
260 | if (isset($this->requestHeaders['authorization'])) {
261 | $key .= $this->requestHeaders['authorization'];
262 | }
263 |
264 | return md5($key);
265 | }
266 |
267 | public function getParsedCacheControl() {
268 | $parsed = array();
269 | $rawCacheControl = $this->getResponseHeader('cache-control');
270 | if ($rawCacheControl) {
271 | $rawCacheControl = str_replace(', ', '&', $rawCacheControl);
272 | parse_str($rawCacheControl, $parsed);
273 | }
274 |
275 | return $parsed;
276 | }
277 |
278 | /**
279 | * @param string $id
280 | * @return string A string representation of the HTTP Request.
281 | */
282 | public function toBatchString($id) {
283 | $str = '';
284 | foreach($this->batchHeaders as $key => $val) {
285 | $str .= $key . ': ' . $val . "\n";
286 | }
287 |
288 | $str .= "Content-ID: $id\n";
289 | $str .= "\n";
290 |
291 | $path = parse_url($this->getUrl(), PHP_URL_PATH);
292 | $str .= $this->getRequestMethod() . ' ' . $path . " HTTP/1.1\n";
293 | foreach($this->getRequestHeaders() as $key => $val) {
294 | $str .= $key . ': ' . $val . "\n";
295 | }
296 |
297 | if ($this->getPostBody()) {
298 | $str .= "\n";
299 | $str .= $this->getPostBody();
300 | }
301 |
302 | return $str;
303 | }
304 | }
305 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/io/Google_IO.php:
--------------------------------------------------------------------------------
1 |
26 | */
27 | interface Google_IO {
28 | /**
29 | * An utility function that first calls $this->auth->sign($request) and then executes makeRequest()
30 | * on that signed request. Used for when a request should be authenticated
31 | * @param Google_HttpRequest $request
32 | * @return Google_HttpRequest $request
33 | */
34 | public function authenticatedRequest(Google_HttpRequest $request);
35 |
36 | /**
37 | * Executes a apIHttpRequest and returns the resulting populated httpRequest
38 | * @param Google_HttpRequest $request
39 | * @return Google_HttpRequest $request
40 | */
41 | public function makeRequest(Google_HttpRequest $request);
42 |
43 | /**
44 | * Set options that update the transport implementation's behavior.
45 | * @param $options
46 | */
47 | public function setOptions($options);
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/io/Google_REST.php:
--------------------------------------------------------------------------------
1 |
22 | * @author Chirag Shah
23 | */
24 | class Google_REST {
25 | /**
26 | * Executes a apiServiceRequest using a RESTful call by transforming it into
27 | * an apiHttpRequest, and executed via apiIO::authenticatedRequest().
28 | *
29 | * @param Google_HttpRequest $req
30 | * @return array decoded result
31 | * @throws Google_ServiceException on server side error (ie: not authenticated,
32 | * invalid or malformed post body, invalid url)
33 | */
34 | static public function execute(Google_HttpRequest $req) {
35 | $httpRequest = Google_Client::$io->makeRequest($req);
36 | $decodedResponse = self::decodeHttpResponse($httpRequest);
37 | $ret = isset($decodedResponse['data'])
38 | ? $decodedResponse['data'] : $decodedResponse;
39 | return $ret;
40 | }
41 |
42 |
43 | /**
44 | * Decode an HTTP Response.
45 | * @static
46 | * @throws Google_ServiceException
47 | * @param Google_HttpRequest $response The http response to be decoded.
48 | * @return mixed|null
49 | */
50 | public static function decodeHttpResponse($response) {
51 | $code = $response->getResponseHttpCode();
52 | $body = $response->getResponseBody();
53 | $decoded = null;
54 |
55 | if ($code != '200' && $code != '201' && $code != '204') {
56 | $decoded = json_decode($body, true);
57 | $err = 'Error calling ' . $response->getRequestMethod() . ' ' . $response->getUrl();
58 | if ($decoded != null && isset($decoded['error']['message']) && isset($decoded['error']['code'])) {
59 | // if we're getting a json encoded error definition, use that instead of the raw response
60 | // body for improved readability
61 | $err .= ": ({$decoded['error']['code']}) {$decoded['error']['message']}";
62 | } else {
63 | $err .= ": ($code) $body";
64 | }
65 |
66 | throw new Google_ServiceException($err, $code, null, $decoded['error']['errors']);
67 | }
68 |
69 | // Only attempt to decode the response, if the response code wasn't (204) 'no content'
70 | if ($code != '204') {
71 | $decoded = json_decode($body, true);
72 | if ($decoded === null || $decoded === "") {
73 | throw new Google_ServiceException("Invalid json in service response: $body");
74 | }
75 | }
76 | return $decoded;
77 | }
78 |
79 | /**
80 | * Parse/expand request parameters and create a fully qualified
81 | * request uri.
82 | * @static
83 | * @param string $servicePath
84 | * @param string $restPath
85 | * @param array $params
86 | * @return string $requestUrl
87 | */
88 | static function createRequestUri($servicePath, $restPath, $params) {
89 | $requestUrl = $servicePath . $restPath;
90 | $uriTemplateVars = array();
91 | $queryVars = array();
92 | foreach ($params as $paramName => $paramSpec) {
93 | // Discovery v1.0 puts the canonical location under the 'location' field.
94 | if (! isset($paramSpec['location'])) {
95 | $paramSpec['location'] = $paramSpec['restParameterType'];
96 | }
97 |
98 | if ($paramSpec['type'] == 'boolean') {
99 | $paramSpec['value'] = ($paramSpec['value']) ? 'true' : 'false';
100 | }
101 | if ($paramSpec['location'] == 'path') {
102 | $uriTemplateVars[$paramName] = $paramSpec['value'];
103 | } else {
104 | if (isset($paramSpec['repeated']) && is_array($paramSpec['value'])) {
105 | foreach ($paramSpec['value'] as $value) {
106 | $queryVars[] = $paramName . '=' . rawurlencode($value);
107 | }
108 | } else {
109 | $queryVars[] = $paramName . '=' . rawurlencode($paramSpec['value']);
110 | }
111 | }
112 | }
113 |
114 | if (count($uriTemplateVars)) {
115 | $uriTemplateParser = new URI_Template_Parser($requestUrl);
116 | $requestUrl = $uriTemplateParser->expand($uriTemplateVars);
117 | }
118 | //FIXME work around for the the uri template lib which url encodes
119 | // the @'s & confuses our servers.
120 | $requestUrl = str_replace('%40', '@', $requestUrl);
121 |
122 | if (count($queryVars)) {
123 | $requestUrl .= '?' . implode($queryVars, '&');
124 | }
125 |
126 | return $requestUrl;
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/io/cacerts.pem:
--------------------------------------------------------------------------------
1 | # Certifcate Authority certificates for validating SSL connections.
2 | #
3 | # This file contains PEM format certificates generated from
4 | # http://mxr.mozilla.org/seamonkey/source/security/nss/lib/ckfw/builtins/certdata.txt
5 | #
6 | # ***** BEGIN LICENSE BLOCK *****
7 | # Version: MPL 1.1/GPL 2.0/LGPL 2.1
8 | #
9 | # The contents of this file are subject to the Mozilla Public License Version
10 | # 1.1 (the "License"); you may not use this file except in compliance with
11 | # the License. You may obtain a copy of the License at
12 | # http://www.mozilla.org/MPL/
13 | #
14 | # Software distributed under the License is distributed on an "AS IS" basis,
15 | # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
16 | # for the specific language governing rights and limitations under the
17 | # License.
18 | #
19 | # The Original Code is the Netscape security libraries.
20 | #
21 | # The Initial Developer of the Original Code is
22 | # Netscape Communications Corporation.
23 | # Portions created by the Initial Developer are Copyright (C) 1994-2000
24 | # the Initial Developer. All Rights Reserved.
25 | #
26 | # Contributor(s):
27 | #
28 | # Alternatively, the contents of this file may be used under the terms of
29 | # either the GNU General Public License Version 2 or later (the "GPL"), or
30 | # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31 | # in which case the provisions of the GPL or the LGPL are applicable instead
32 | # of those above. If you wish to allow use of your version of this file only
33 | # under the terms of either the GPL or the LGPL, and not to allow others to
34 | # use your version of this file under the terms of the MPL, indicate your
35 | # decision by deleting the provisions above and replace them with the notice
36 | # and other provisions required by the GPL or the LGPL. If you do not delete
37 | # the provisions above, a recipient may use your version of this file under
38 | # the terms of any one of the MPL, the GPL or the LGPL.
39 | #
40 | # ***** END LICENSE BLOCK *****
41 |
42 | Verisign/RSA Secure Server CA
43 | =============================
44 |
45 | -----BEGIN CERTIFICATE-----
46 | MIICNDCCAaECEAKtZn5ORf5eV288mBle3cAwDQYJKoZIhvcNAQECBQAwXzELMAkG
47 | A1UEBhMCVVMxIDAeBgNVBAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYD
48 | VQQLEyVTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk0
49 | MTEwOTAwMDAwMFoXDTEwMDEwNzIzNTk1OVowXzELMAkGA1UEBhMCVVMxIDAeBgNV
50 | BAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2Vy
51 | dmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGbMA0GCSqGSIb3DQEBAQUAA4GJ
52 | ADCBhQJ+AJLOesGugz5aqomDV6wlAXYMra6OLDfO6zV4ZFQD5YRAUcm/jwjiioII
53 | 0haGN1XpsSECrXZogZoFokvJSyVmIlZsiAeP94FZbYQHZXATcXY+m3dM41CJVphI
54 | uR2nKRoTLkoRWZweFdVJVCxzOmmCsZc5nG1wZ0jl3S3WyB57AgMBAAEwDQYJKoZI
55 | hvcNAQECBQADfgBl3X7hsuyw4jrg7HFGmhkRuNPHoLQDQCYCPgmc4RKz0Vr2N6W3
56 | YQO2WxZpO8ZECAyIUwxrl0nHPjXcbLm7qt9cuzovk2C2qUtN8iD3zV9/ZHuO3ABc
57 | 1/p3yjkWWW8O6tO1g39NTUJWdrTJXwT4OPjr0l91X817/OWOgHz8UA==
58 | -----END CERTIFICATE-----
59 |
60 | Thawte Personal Basic CA
61 | ========================
62 |
63 | -----BEGIN CERTIFICATE-----
64 | MIIDITCCAoqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCByzELMAkGA1UEBhMCWkEx
65 | FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD
66 | VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT
67 | ZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFBlcnNvbmFsIEJhc2lj
68 | IENBMSgwJgYJKoZIhvcNAQkBFhlwZXJzb25hbC1iYXNpY0B0aGF3dGUuY29tMB4X
69 | DTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgcsxCzAJBgNVBAYTAlpBMRUw
70 | EwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEaMBgGA1UE
71 | ChMRVGhhd3RlIENvbnN1bHRpbmcxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2Vy
72 | dmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQZXJzb25hbCBCYXNpYyBD
73 | QTEoMCYGCSqGSIb3DQEJARYZcGVyc29uYWwtYmFzaWNAdGhhd3RlLmNvbTCBnzAN
74 | BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvLyTU23AUE+CFeZIlDWmWr5vQvoPR+53
75 | dXLdjUmbllegeNTKP1GzaQuRdhciB5dqxFGTS+CN7zeVoQxN2jSQHReJl+A1OFdK
76 | wPQIcOk8RHtQfmGakOMj04gRRif1CwcOu93RfyAKiLlWCy4cgNrx454p7xS9CkT7
77 | G1sY0b8jkyECAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQF
78 | AAOBgQAt4plrsD16iddZopQBHyvdEktTwq1/qqcAXJFAVyVKOKqEcLnZgA+le1z7
79 | c8a914phXAPjLSeoF+CEhULcXpvGt7Jtu3Sv5D/Lp7ew4F2+eIMllNLbgQ95B21P
80 | 9DkVWlIBe94y1k049hJcBlDfBVu9FEuh3ym6O0GN92NWod8isQ==
81 | -----END CERTIFICATE-----
82 |
83 | Thawte Personal Premium CA
84 | ==========================
85 |
86 | -----BEGIN CERTIFICATE-----
87 | MIIDKTCCApKgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBzzELMAkGA1UEBhMCWkEx
88 | FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD
89 | VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT
90 | ZXJ2aWNlcyBEaXZpc2lvbjEjMCEGA1UEAxMaVGhhd3RlIFBlcnNvbmFsIFByZW1p
91 | dW0gQ0ExKjAoBgkqhkiG9w0BCQEWG3BlcnNvbmFsLXByZW1pdW1AdGhhd3RlLmNv
92 | bTAeFw05NjAxMDEwMDAwMDBaFw0yMDEyMzEyMzU5NTlaMIHPMQswCQYDVQQGEwJa
93 | QTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRvd24xGjAY
94 | BgNVBAoTEVRoYXd0ZSBDb25zdWx0aW5nMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9u
95 | IFNlcnZpY2VzIERpdmlzaW9uMSMwIQYDVQQDExpUaGF3dGUgUGVyc29uYWwgUHJl
96 | bWl1bSBDQTEqMCgGCSqGSIb3DQEJARYbcGVyc29uYWwtcHJlbWl1bUB0aGF3dGUu
97 | Y29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJZtn4B0TPuYwu8KHvE0Vs
98 | Bd/eJxZRNkERbGw77f4QfRKe5ZtCmv5gMcNmt3M6SK5O0DI3lIi1DbbZ8/JE2dWI
99 | Et12TfIa/G8jHnrx2JhFTgcQ7xZC0EN1bUre4qrJMf8fAHB8Zs8QJQi6+u4A6UYD
100 | ZicRFTuqW/KY3TZCstqIdQIDAQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
101 | SIb3DQEBBAUAA4GBAGk2ifc0KjNyL2071CKyuG+axTZmDhs8obF1Wub9NdP4qPIH
102 | b4Vnjt4rueIXsDqg8A6iAJrf8xQVbrvIhVqYgPn/vnQdPfP+MCXRNzRn+qVxeTBh
103 | KXLA4CxM+1bkOqhv5TJZUtt1KFBZDPgLGeSs2a+WjS9Q2wfD6h+rM+D1KzGJ
104 | -----END CERTIFICATE-----
105 |
106 | Thawte Personal Freemail CA
107 | ===========================
108 |
109 | -----BEGIN CERTIFICATE-----
110 | MIIDLTCCApagAwIBAgIBADANBgkqhkiG9w0BAQQFADCB0TELMAkGA1UEBhMCWkEx
111 | FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD
112 | VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT
113 | ZXJ2aWNlcyBEaXZpc2lvbjEkMCIGA1UEAxMbVGhhd3RlIFBlcnNvbmFsIEZyZWVt
114 | YWlsIENBMSswKQYJKoZIhvcNAQkBFhxwZXJzb25hbC1mcmVlbWFpbEB0aGF3dGUu
115 | Y29tMB4XDTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgdExCzAJBgNVBAYT
116 | AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEa
117 | MBgGA1UEChMRVGhhd3RlIENvbnN1bHRpbmcxKDAmBgNVBAsTH0NlcnRpZmljYXRp
118 | b24gU2VydmljZXMgRGl2aXNpb24xJDAiBgNVBAMTG1RoYXd0ZSBQZXJzb25hbCBG
119 | cmVlbWFpbCBDQTErMCkGCSqGSIb3DQEJARYccGVyc29uYWwtZnJlZW1haWxAdGhh
120 | d3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1GnX1LCUZFtx6UfY
121 | DFG26nKRsIRefS0Nj3sS34UldSh0OkIsYyeflXtL734Zhx2G6qPduc6WZBrCFG5E
122 | rHzmj+hND3EfQDimAKOHePb5lIZererAXnbr2RSjXW56fAylS1V/Bhkpf56aJtVq
123 | uzgkCGqYx7Hao5iR/Xnb5VrEHLkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zAN
124 | BgkqhkiG9w0BAQQFAAOBgQDH7JJ+Tvj1lqVnYiqk8E0RYNBvjWBYYawmu1I1XAjP
125 | MPuoSpaKH2JCI4wXD/S6ZJwXrEcp352YXtJsYHFcoqzceePnbgBHH7UNKOgCneSa
126 | /RP0ptl8sfjcXyMmCZGAc9AUG95DqYMl8uacLxXK/qarigd1iwzdUYRr5PjRznei
127 | gQ==
128 | -----END CERTIFICATE-----
129 |
130 | Thawte Server CA
131 | ================
132 |
133 | -----BEGIN CERTIFICATE-----
134 | MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkEx
135 | FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD
136 | VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv
137 | biBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEm
138 | MCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wHhcNOTYwODAx
139 | MDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT
140 | DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3
141 | dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNl
142 | cyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3
143 | DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD
144 | gY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl/Kj0R1HahbUgdJSGHg91
145 | yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg71CcEJRCX
146 | L+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGj
147 | EzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG
148 | 7oWDTSEwjsrZqG9JGubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6e
149 | QNuozDJ0uW8NxuOzRAvZim+aKZuZGCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZ
150 | qdq5snUb9kLy78fyGPmJvKP/iiMucEc=
151 | -----END CERTIFICATE-----
152 |
153 | Thawte Premium Server CA
154 | ========================
155 |
156 | -----BEGIN CERTIFICATE-----
157 | MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx
158 | FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD
159 | VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv
160 | biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy
161 | dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t
162 | MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB
163 | MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG
164 | A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp
165 | b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl
166 | cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv
167 | bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE
168 | VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ
169 | ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR
170 | uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
171 | 9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI
172 | hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM
173 | pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg==
174 | -----END CERTIFICATE-----
175 |
176 | Equifax Secure CA
177 | =================
178 |
179 | -----BEGIN CERTIFICATE-----
180 | MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV
181 | UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy
182 | dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1
183 | MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx
184 | dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B
185 | AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f
186 | BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A
187 | cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC
188 | AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ
189 | MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm
190 | aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw
191 | ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj
192 | IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF
193 | MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA
194 | A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
195 | 7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh
196 | 1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4
197 | -----END CERTIFICATE-----
198 |
199 | Verisign Class 1 Public Primary Certification Authority
200 | =======================================================
201 |
202 | -----BEGIN CERTIFICATE-----
203 | MIICPTCCAaYCEQDNun9W8N/kvFT+IqyzcqpVMA0GCSqGSIb3DQEBAgUAMF8xCzAJ
204 | BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xh
205 | c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05
206 | NjAxMjkwMDAwMDBaFw0yODA4MDEyMzU5NTlaMF8xCzAJBgNVBAYTAlVTMRcwFQYD
207 | VQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMSBQdWJsaWMgUHJp
208 | bWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOB
209 | jQAwgYkCgYEA5Rm/baNWYS2ZSHH2Z965jeu3noaACpEO+jglr0aIguVzqKCbJF0N
210 | H8xlbgyw0FaEGIeaBpsQoXPftFg5a27B9hXVqKg/qhIGjTGsf7A01480Z4gJzRQR
211 | 4k5FVmkfeAKA2txHkSm7NsljXMXg1y2He6G3MrB7MLoqLzGq7qNn2tsCAwEAATAN
212 | BgkqhkiG9w0BAQIFAAOBgQBMP7iLxmjf7kMzDl3ppssHhE16M/+SG/Q2rdiVIjZo
213 | EWx8QszznC7EBz8UsA9P/5CSdvnivErpj82ggAr3xSnxgiJduLHdgSOjeyUVRjB5
214 | FvjqBUuUfx3CHMjjt/QQQDwTw18fU+hI5Ia0e6E1sHslurjTjqs/OJ0ANACY89Fx
215 | lA==
216 | -----END CERTIFICATE-----
217 |
218 | Verisign Class 2 Public Primary Certification Authority
219 | =======================================================
220 |
221 | -----BEGIN CERTIFICATE-----
222 | MIICPDCCAaUCEC0b/EoXjaOR6+f/9YtFvgswDQYJKoZIhvcNAQECBQAwXzELMAkG
223 | A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
224 | cyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
225 | MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
226 | BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAyIFB1YmxpYyBQcmlt
227 | YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
228 | ADCBiQKBgQC2WoujDWojg4BrzzmH9CETMwZMJaLtVRKXxaeAufqDwSCg+i8VDXyh
229 | YGt+eSz6Bg86rvYbb7HS/y8oUl+DfUvEerf4Zh+AVPy3wo5ZShRXRtGak75BkQO7
230 | FYCTXOvnzAhsPz6zSvz/S2wj1VCCJkQZjiPDceoZJEcEnnW/yKYAHwIDAQABMA0G
231 | CSqGSIb3DQEBAgUAA4GBAIobK/o5wXTXXtgZZKJYSi034DNHD6zt96rbHuSLBlxg
232 | J8pFUs4W7z8GZOeUaHxgMxURaa+dYo2jA1Rrpr7l7gUYYAS/QoD90KioHgE796Nc
233 | r6Pc5iaAIzy4RHT3Cq5Ji2F4zCS/iIqnDupzGUH9TQPwiNHleI2lKk/2lw0Xd8rY
234 | -----END CERTIFICATE-----
235 |
236 | Verisign Class 3 Public Primary Certification Authority
237 | =======================================================
238 |
239 | -----BEGIN CERTIFICATE-----
240 | MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG
241 | A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
242 | cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
243 | MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
244 | BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
245 | YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
246 | ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
247 | BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
248 | I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
249 | CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do
250 | lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc
251 | AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k
252 | -----END CERTIFICATE-----
253 |
254 | Verisign Class 1 Public Primary Certification Authority - G2
255 | ============================================================
256 |
257 | -----BEGIN CERTIFICATE-----
258 | MIIDAjCCAmsCEEzH6qqYPnHTkxD4PTqJkZIwDQYJKoZIhvcNAQEFBQAwgcExCzAJ
259 | BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh
260 | c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy
261 | MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp
262 | emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X
263 | DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw
264 | FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMg
265 | UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo
266 | YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5
267 | MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB
268 | AQUAA4GNADCBiQKBgQCq0Lq+Fi24g9TK0g+8djHKlNgdk4xWArzZbxpvUjZudVYK
269 | VdPfQ4chEWWKfo+9Id5rMj8bhDSVBZ1BNeuS65bdqlk/AVNtmU/t5eIqWpDBucSm
270 | Fc/IReumXY6cPvBkJHalzasab7bYe1FhbqZ/h8jit+U03EGI6glAvnOSPWvndQID
271 | AQABMA0GCSqGSIb3DQEBBQUAA4GBAKlPww3HZ74sy9mozS11534Vnjty637rXC0J
272 | h9ZrbWB85a7FkCMMXErQr7Fd88e2CtvgFZMN3QO8x3aKtd1Pw5sTdbgBwObJW2ul
273 | uIncrKTdcu1OofdPvAbT6shkdHvClUGcZXNY8ZCaPGqxmMnEh7zPRW1F4m4iP/68
274 | DzFc6PLZ
275 | -----END CERTIFICATE-----
276 |
277 | Verisign Class 2 Public Primary Certification Authority - G2
278 | ============================================================
279 |
280 | -----BEGIN CERTIFICATE-----
281 | MIIDAzCCAmwCEQC5L2DMiJ+hekYJuFtwbIqvMA0GCSqGSIb3DQEBBQUAMIHBMQsw
282 | CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0Ns
283 | YXNzIDIgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH
284 | MjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9y
285 | aXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazAe
286 | Fw05ODA1MTgwMDAwMDBaFw0yODA4MDEyMzU5NTlaMIHBMQswCQYDVQQGEwJVUzEX
287 | MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGlj
288 | IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMx
289 | KGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
290 | eTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazCBnzANBgkqhkiG9w0B
291 | AQEFAAOBjQAwgYkCgYEAp4gBIXQs5xoD8JjhlzwPIQjxnNuX6Zr8wgQGE75fUsjM
292 | HiwSViy4AWkszJkfrbCWrnkE8hM5wXuYuggs6MKEEyyqaekJ9MepAqRCwiNPStjw
293 | DqL7MWzJ5m+ZJwf15vRMeJ5t60aG+rmGyVTyssSv1EYcWskVMP8NbPUtDm3Of3cC
294 | AwEAATANBgkqhkiG9w0BAQUFAAOBgQByLvl/0fFx+8Se9sVeUYpAmLho+Jscg9ji
295 | nb3/7aHmZuovCfTK1+qlK5X2JGCGTUQug6XELaDTrnhpb3LabK4I8GOSN+a7xDAX
296 | rXfMSTWqz9iP0b63GJZHc2pUIjRkLbYWm1lbtFFZOrMLFPQS32eg9K0yZF6xRnIn
297 | jBJ7xUS0rg==
298 | -----END CERTIFICATE-----
299 |
300 | Verisign Class 3 Public Primary Certification Authority - G2
301 | ============================================================
302 |
303 | -----BEGIN CERTIFICATE-----
304 | MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJ
305 | BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh
306 | c3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy
307 | MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp
308 | emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X
309 | DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw
310 | FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMg
311 | UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo
312 | YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5
313 | MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB
314 | AQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4
315 | pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg0
316 | 13gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwID
317 | AQABMA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSk
318 | U01UbSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i
319 | F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpY
320 | oJ2daZH9
321 | -----END CERTIFICATE-----
322 |
323 | Verisign Class 4 Public Primary Certification Authority - G2
324 | ============================================================
325 |
326 | -----BEGIN CERTIFICATE-----
327 | MIIDAjCCAmsCEDKIjprS9esTR/h/xCA3JfgwDQYJKoZIhvcNAQEFBQAwgcExCzAJ
328 | BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh
329 | c3MgNCBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy
330 | MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp
331 | emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X
332 | DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw
333 | FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgNCBQdWJsaWMg
334 | UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo
335 | YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5
336 | MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB
337 | AQUAA4GNADCBiQKBgQC68OTP+cSuhVS5B1f5j8V/aBH4xBewRNzjMHPVKmIquNDM
338 | HO0oW369atyzkSTKQWI8/AIBvxwWMZQFl3Zuoq29YRdsTjCG8FE3KlDHqGKB3FtK
339 | qsGgtG7rL+VXxbErQHDbWk2hjh+9Ax/YA9SPTJlxvOKCzFjomDqG04Y48wApHwID
340 | AQABMA0GCSqGSIb3DQEBBQUAA4GBAIWMEsGnuVAVess+rLhDityq3RS6iYF+ATwj
341 | cSGIL4LcY/oCRaxFWdcqWERbt5+BO5JoPeI3JPV7bI92NZYJqFmduc4jq3TWg/0y
342 | cyfYaT5DdPauxYma51N86Xv2S/PBZYPejYqcPIiNOVn8qj8ijaHBZlCBckztImRP
343 | T8qAkbYp
344 | -----END CERTIFICATE-----
345 |
346 | Verisign Class 1 Public Primary Certification Authority - G3
347 | ============================================================
348 |
349 | -----BEGIN CERTIFICATE-----
350 | MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQsw
351 | CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
352 | cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
353 | LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
354 | aWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
355 | dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
356 | VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
357 | aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
358 | bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
359 | IENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
360 | LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN2E1Lm0+afY8wR4
361 | nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/EbRrsC+MO
362 | 8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjV
363 | ojYJrKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjb
364 | PG7PoBMAGrgnoeS+Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP2
365 | 6KbqxzcSXKMpHgLZ2x87tNcPVkeBFQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vr
366 | n5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAq2aN17O6x5q25lXQBfGfMY1a
367 | qtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/Ny9Sn2WCVhDr4
368 | wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3
369 | ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrs
370 | pSCAaWihT37ha88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4
371 | E1Z5T21Q6huwtVexN2ZYI/PcD98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g==
372 | -----END CERTIFICATE-----
373 |
374 | Verisign Class 2 Public Primary Certification Authority - G3
375 | ============================================================
376 |
377 | -----BEGIN CERTIFICATE-----
378 | MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJ
379 | BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVy
380 | aVNpZ24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24s
381 | IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNp
382 | Z24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
383 | eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJBgNV
384 | BAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNp
385 | Z24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIElu
386 | Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24g
387 | Q2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt
388 | IEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArwoNwtUs22e5LeWU
389 | J92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6tW8UvxDO
390 | JxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUY
391 | wZF7C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9o
392 | koqQHgiBVrKtaaNS0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjN
393 | qWm6o+sdDZykIKbBoMXRRkwXbdKsZj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/E
394 | Srg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0JhU8wI1NQ0kdvekhktdmnLfe
395 | xbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf0xwLRtxyID+u
396 | 7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU
397 | sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RI
398 | sH/7NiXaldDxJBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTP
399 | cjnhsUPgKM+351psE2tJs//jGHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q
400 | -----END CERTIFICATE-----
401 |
402 | Verisign Class 3 Public Primary Certification Authority - G3
403 | ============================================================
404 |
405 | -----BEGIN CERTIFICATE-----
406 | MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw
407 | CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
408 | cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
409 | LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
410 | aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
411 | dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
412 | VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
413 | aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
414 | bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
415 | IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
416 | LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b
417 | N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t
418 | KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu
419 | kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm
420 | CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ
421 | Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu
422 | imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te
423 | 2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe
424 | DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
425 | /Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p
426 | F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt
427 | TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
428 | -----END CERTIFICATE-----
429 |
430 | Verisign Class 4 Public Primary Certification Authority - G3
431 | ============================================================
432 |
433 | -----BEGIN CERTIFICATE-----
434 | MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQsw
435 | CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
436 | cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
437 | LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
438 | aWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
439 | dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
440 | VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
441 | aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
442 | bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
443 | IENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
444 | LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1
445 | GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ
446 | +mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0Gbd
447 | U6LM8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLm
448 | NxdLMEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY
449 | ufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/
450 | ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1WrIhVZPMq1
451 | CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXttmhwwjIDLk5Mq
452 | g6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm
453 | fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c
454 | 2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/
455 | bLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg==
456 | -----END CERTIFICATE-----
457 |
458 | Equifax Secure Global eBusiness CA
459 | ==================================
460 |
461 | -----BEGIN CERTIFICATE-----
462 | MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc
463 | MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT
464 | ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw
465 | MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj
466 | dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l
467 | c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC
468 | UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc
469 | 58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/
470 | o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH
471 | MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr
472 | aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA
473 | A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA
474 | Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv
475 | 8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV
476 | -----END CERTIFICATE-----
477 |
478 | Equifax Secure eBusiness CA 1
479 | =============================
480 |
481 | -----BEGIN CERTIFICATE-----
482 | MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEc
483 | MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBT
484 | ZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQw
485 | MDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5j
486 | LjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwgZ8wDQYJ
487 | KoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ1MRo
488 | RvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBu
489 | WqDZQu4aIZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKw
490 | Env+j6YDAgMBAAGjZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTAD
491 | AQH/MB8GA1UdIwQYMBaAFEp4MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRK
492 | eDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZM
493 | zfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+
494 | WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN
495 | /Bf+KpYrtWKmpj29f5JZzVoqgrI3eQ==
496 | -----END CERTIFICATE-----
497 |
498 | Equifax Secure eBusiness CA 2
499 | =============================
500 |
501 | -----BEGIN CERTIFICATE-----
502 | MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV
503 | UzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2Vj
504 | dXJlIGVCdXNpbmVzcyBDQS0yMB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0
505 | NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkVxdWlmYXggU2VjdXJlMSYwJAYD
506 | VQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCBnzANBgkqhkiG9w0B
507 | AQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn2Z0G
508 | vxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/
509 | BPO3QSQ5BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0C
510 | AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEX
511 | MBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJl
512 | IGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTkw
513 | NjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9euSBIplBq
514 | y/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQF
515 | MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA
516 | A4GBAAyGgq3oThr1jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy
517 | 0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1
518 | E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUmV+GRMOrN
519 | -----END CERTIFICATE-----
520 |
521 | Thawte Time Stamping CA
522 | =======================
523 |
524 | -----BEGIN CERTIFICATE-----
525 | MIICoTCCAgqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBizELMAkGA1UEBhMCWkEx
526 | FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzAN
527 | BgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24xHzAd
528 | BgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcgQ0EwHhcNOTcwMTAxMDAwMDAwWhcN
529 | MjAxMjMxMjM1OTU5WjCBizELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4g
530 | Q2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzANBgNVBAoTBlRoYXd0ZTEdMBsG
531 | A1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1l
532 | c3RhbXBpbmcgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANYrWHhhRYZT
533 | 6jR7UZztsOYuGA7+4F+oJ9O0yeB8WU4WDnNUYMF/9p8u6TqFJBU820cEY8OexJQa
534 | Wt9MevPZQx08EHp5JduQ/vBR5zDWQQD9nyjfeb6Uu522FOMjhdepQeBMpHmwKxqL
535 | 8vg7ij5FrHGSALSQQZj7X+36ty6K+Ig3AgMBAAGjEzARMA8GA1UdEwEB/wQFMAMB
536 | Af8wDQYJKoZIhvcNAQEEBQADgYEAZ9viwuaHPUCDhjc1fR/OmsMMZiCouqoEiYbC
537 | 9RAIDb/LogWK0E02PvTX72nGXuSwlG9KuefeW4i2e9vjJ+V2w/A1wcu1J5szedyQ
538 | pgCed/r8zSeUQhac0xxo7L9c3eWpexAKMnRUEzGLhQOEkbdYATAUOK8oyvyxUBkZ
539 | CayJSdM=
540 | -----END CERTIFICATE-----
541 |
542 | thawte Primary Root CA
543 | ======================
544 |
545 | -----BEGIN CERTIFICATE-----
546 | MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB
547 | qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
548 | Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
549 | MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
550 | BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw
551 | NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j
552 | LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG
553 | A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
554 | IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG
555 | SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs
556 | W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta
557 | 3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk
558 | 6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6
559 | Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J
560 | NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA
561 | MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP
562 | r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU
563 | DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz
564 | YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
565 | xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2
566 | /qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/
567 | LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7
568 | jVaMaA==
569 | -----END CERTIFICATE-----
570 |
571 | VeriSign Class 3 Public Primary Certification Authority - G5
572 | ============================================================
573 |
574 | -----BEGIN CERTIFICATE-----
575 | MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
576 | yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
577 | ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
578 | U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
579 | ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
580 | aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
581 | MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
582 | ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
583 | biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
584 | U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
585 | aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
586 | nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
587 | t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
588 | SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
589 | BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
590 | rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
591 | NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
592 | BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
593 | BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
594 | aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
595 | MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
596 | p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
597 | 5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
598 | WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
599 | 4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
600 | hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
601 | -----END CERTIFICATE-----
602 |
603 | Entrust.net Secure Server Certification Authority
604 | =================================================
605 |
606 | -----BEGIN CERTIFICATE-----
607 | MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC
608 | VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u
609 | ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc
610 | KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u
611 | ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1
612 | MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE
613 | ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j
614 | b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF
615 | bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg
616 | U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA
617 | A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/
618 | I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3
619 | wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC
620 | AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb
621 | oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5
622 | BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p
623 | dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk
624 | MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp
625 | b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu
626 | dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0
627 | MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi
628 | E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa
629 | MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI
630 | hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN
631 | 95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd
632 | 2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI=
633 | -----END CERTIFICATE-----
634 |
635 | Go Daddy Certification Authority Root Certificate Bundle
636 | ========================================================
637 |
638 | -----BEGIN CERTIFICATE-----
639 | MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx
640 | ITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g
641 | RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMTYw
642 | MTU0MzdaFw0yNjExMTYwMTU0MzdaMIHKMQswCQYDVQQGEwJVUzEQMA4GA1UECBMH
643 | QXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5j
644 | b20sIEluYy4xMzAxBgNVBAsTKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j
645 | b20vcmVwb3NpdG9yeTEwMC4GA1UEAxMnR28gRGFkZHkgU2VjdXJlIENlcnRpZmlj
646 | YXRpb24gQXV0aG9yaXR5MREwDwYDVQQFEwgwNzk2OTI4NzCCASIwDQYJKoZIhvcN
647 | AQEBBQADggEPADCCAQoCggEBAMQt1RWMnCZM7DI161+4WQFapmGBWTtwY6vj3D3H
648 | KrjJM9N55DrtPDAjhI6zMBS2sofDPZVUBJ7fmd0LJR4h3mUpfjWoqVTr9vcyOdQm
649 | VZWt7/v+WIbXnvQAjYwqDL1CBM6nPwT27oDyqu9SoWlm2r4arV3aLGbqGmu75RpR
650 | SgAvSMeYddi5Kcju+GZtCpyz8/x4fKL4o/K1w/O5epHBp+YlLpyo7RJlbmr2EkRT
651 | cDCVw5wrWCs9CHRK8r5RsL+H0EwnWGu1NcWdrxcx+AuP7q2BNgWJCJjPOq8lh8BJ
652 | 6qf9Z/dFjpfMFDniNoW1fho3/Rb2cRGadDAW/hOUoz+EDU8CAwEAAaOCATIwggEu
653 | MB0GA1UdDgQWBBT9rGEyk2xF1uLuhV+auud2mWjM5zAfBgNVHSMEGDAWgBTSxLDS
654 | kdRMEXGzYcs9of7dqGrU4zASBgNVHRMBAf8ECDAGAQH/AgEAMDMGCCsGAQUFBwEB
655 | BCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZ29kYWRkeS5jb20wRgYDVR0f
656 | BD8wPTA7oDmgN4Y1aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBv
657 | c2l0b3J5L2dkcm9vdC5jcmwwSwYDVR0gBEQwQjBABgRVHSAAMDgwNgYIKwYBBQUH
658 | AgEWKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeTAO
659 | BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBANKGwOy9+aG2Z+5mC6IG
660 | OgRQjhVyrEp0lVPLN8tESe8HkGsz2ZbwlFalEzAFPIUyIXvJxwqoJKSQ3kbTJSMU
661 | A2fCENZvD117esyfxVgqwcSeIaha86ykRvOe5GPLL5CkKSkB2XIsKd83ASe8T+5o
662 | 0yGPwLPk9Qnt0hCqU7S+8MxZC9Y7lhyVJEnfzuz9p0iRFEUOOjZv2kWzRaJBydTX
663 | RE4+uXR21aITVSzGh6O1mawGhId/dQb8vxRMDsxuxN89txJx9OjxUUAiKEngHUuH
664 | qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV
665 | U+4=
666 | -----END CERTIFICATE-----
667 | -----BEGIN CERTIFICATE-----
668 | MIIE+zCCBGSgAwIBAgICAQ0wDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1Zh
669 | bGlDZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIElu
670 | Yy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24g
671 | QXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAe
672 | BgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTA0MDYyOTE3MDYyMFoX
673 | DTI0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBE
674 | YWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3MgMiBDZXJ0
675 | aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgC
676 | ggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv
677 | 2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+q
678 | N1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiO
679 | r18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lN
680 | f4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+YihfukEH
681 | U1jPEX44dMX4/7VpkI+EdOqXG68CAQOjggHhMIIB3TAdBgNVHQ4EFgQU0sSw0pHU
682 | TBFxs2HLPaH+3ahq1OMwgdIGA1UdIwSByjCBx6GBwaSBvjCBuzEkMCIGA1UEBxMb
683 | VmFsaUNlcnQgVmFsaWRhdGlvbiBOZXR3b3JrMRcwFQYDVQQKEw5WYWxpQ2VydCwg
684 | SW5jLjE1MDMGA1UECxMsVmFsaUNlcnQgQ2xhc3MgMiBQb2xpY3kgVmFsaWRhdGlv
685 | biBBdXRob3JpdHkxITAfBgNVBAMTGGh0dHA6Ly93d3cudmFsaWNlcnQuY29tLzEg
686 | MB4GCSqGSIb3DQEJARYRaW5mb0B2YWxpY2VydC5jb22CAQEwDwYDVR0TAQH/BAUw
687 | AwEB/zAzBggrBgEFBQcBAQQnMCUwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLmdv
688 | ZGFkZHkuY29tMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jZXJ0aWZpY2F0ZXMu
689 | Z29kYWRkeS5jb20vcmVwb3NpdG9yeS9yb290LmNybDBLBgNVHSAERDBCMEAGBFUd
690 | IAAwODA2BggrBgEFBQcCARYqaHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNv
691 | bS9yZXBvc2l0b3J5MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOBgQC1
692 | QPmnHfbq/qQaQlpE9xXUhUaJwL6e4+PrxeNYiY+Sn1eocSxI0YGyeR+sBjUZsE4O
693 | WBsUs5iB0QQeyAfJg594RAoYC5jcdnplDQ1tgMQLARzLrUc+cb53S8wGd9D0Vmsf
694 | SxOaFIqII6hR8INMqzW/Rn453HWkrugp++85j09VZw==
695 | -----END CERTIFICATE-----
696 | -----BEGIN CERTIFICATE-----
697 | MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
698 | IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
699 | BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
700 | aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
701 | 9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy
702 | NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
703 | azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
704 | YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
705 | Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
706 | cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY
707 | dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9
708 | WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS
709 | v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v
710 | UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu
711 | IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC
712 | W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd
713 | -----END CERTIFICATE-----
714 |
715 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/service/Google_BatchRequest.php:
--------------------------------------------------------------------------------
1 |
20 | */
21 | class Google_BatchRequest {
22 | /** @var string Multipart Boundary. */
23 | private $boundary;
24 |
25 | /** @var array service requests to be executed. */
26 | private $requests = array();
27 |
28 | public function __construct($boundary = false) {
29 | $boundary = (false == $boundary) ? mt_rand() : $boundary;
30 | $this->boundary = str_replace('"', '', $boundary);
31 | }
32 |
33 | public function add(Google_HttpRequest $request, $key = false) {
34 | if (false == $key) {
35 | $key = mt_rand();
36 | }
37 |
38 | $this->requests[$key] = $request;
39 | }
40 |
41 | public function execute() {
42 | $body = '';
43 |
44 | /** @var Google_HttpRequest $req */
45 | foreach($this->requests as $key => $req) {
46 | $body .= "--{$this->boundary}\n";
47 | $body .= $req->toBatchString($key) . "\n";
48 | }
49 |
50 | $body = rtrim($body);
51 | $body .= "\n--{$this->boundary}--";
52 |
53 | global $apiConfig;
54 | $url = $apiConfig['basePath'] . '/batch';
55 | $httpRequest = new Google_HttpRequest($url, 'POST');
56 | $httpRequest->setRequestHeaders(array(
57 | 'Content-Type' => 'multipart/mixed; boundary=' . $this->boundary));
58 |
59 | $httpRequest->setPostBody($body);
60 | $response = Google_Client::$io->makeRequest($httpRequest);
61 |
62 | $response = $this->parseResponse($response);
63 | return $response;
64 | }
65 |
66 | public function parseResponse(Google_HttpRequest $response) {
67 | $contentType = $response->getResponseHeader('content-type');
68 | $contentType = explode(';', $contentType);
69 | $boundary = false;
70 | foreach($contentType as $part) {
71 | $part = (explode('=', $part, 2));
72 | if (isset($part[0]) && 'boundary' == trim($part[0])) {
73 | $boundary = $part[1];
74 | }
75 | }
76 |
77 | $body = $response->getResponseBody();
78 | if ($body) {
79 | $body = str_replace("--$boundary--", "--$boundary", $body);
80 | $parts = explode("--$boundary", $body);
81 | $responses = array();
82 |
83 | foreach($parts as $part) {
84 | $part = trim($part);
85 | if (!empty($part)) {
86 | list($metaHeaders, $part) = explode("\r\n\r\n", $part, 2);
87 | $metaHeaders = Google_CurlIO::parseResponseHeaders($metaHeaders);
88 |
89 | $status = substr($part, 0, strpos($part, "\n"));
90 | $status = explode(" ", $status);
91 | $status = $status[1];
92 |
93 | list($partHeaders, $partBody) = Google_CurlIO::parseHttpResponse($part, false);
94 | $response = new Google_HttpRequest("");
95 | $response->setResponseHttpCode($status);
96 | $response->setResponseHeaders($partHeaders);
97 | $response->setResponseBody($partBody);
98 | $response = Google_REST::decodeHttpResponse($response);
99 |
100 | // Need content id.
101 | $responses[$metaHeaders['content-id']] = $response;
102 | }
103 | }
104 |
105 | return $responses;
106 | }
107 |
108 | return null;
109 | }
110 | }
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/service/Google_MediaFileUpload.php:
--------------------------------------------------------------------------------
1 |
20 | *
21 | */
22 | class Google_MediaFileUpload {
23 | const UPLOAD_MEDIA_TYPE = 'media';
24 | const UPLOAD_MULTIPART_TYPE = 'multipart';
25 | const UPLOAD_RESUMABLE_TYPE = 'resumable';
26 |
27 | /** @var string $mimeType */
28 | public $mimeType;
29 |
30 | /** @var string $data */
31 | public $data;
32 |
33 | /** @var bool $resumable */
34 | public $resumable;
35 |
36 | /** @var int $chunkSize */
37 | public $chunkSize;
38 |
39 | /** @var int $size */
40 | public $size;
41 |
42 | /** @var string $resumeUri */
43 | public $resumeUri;
44 |
45 | /** @var int $progress */
46 | public $progress;
47 |
48 | /**
49 | * @param $mimeType string
50 | * @param $data string The bytes you want to upload.
51 | * @param $resumable bool
52 | * @param bool $chunkSize File will be uploaded in chunks of this many bytes.
53 | * only used if resumable=True
54 | */
55 | public function __construct($mimeType, $data, $resumable=false, $chunkSize=false) {
56 | $this->mimeType = $mimeType;
57 | $this->data = $data;
58 | $this->size = strlen($this->data);
59 | $this->resumable = $resumable;
60 | if(!$chunkSize) {
61 | $this->chunkSize = 256 * 1024;
62 | }
63 |
64 | $this->progress = 0;
65 | }
66 |
67 | /**
68 | * @static
69 | * @param $meta
70 | * @param $params
71 | * @return array|bool
72 | */
73 | public static function process($meta, &$params) {
74 | $payload = array();
75 | $meta = is_string($meta) ? json_decode($meta, true) : $meta;
76 | $uploadType = self::getUploadType($meta, $payload, $params);
77 | if (!$uploadType) {
78 | // Process as a normal API request.
79 | return false;
80 | }
81 |
82 | // Process as a media upload request.
83 | $params['uploadType'] = array(
84 | 'type' => 'string',
85 | 'location' => 'query',
86 | 'value' => $uploadType,
87 | );
88 |
89 | if (isset($params['file'])) {
90 | // This is a standard file upload with curl.
91 | $file = $params['file']['value'];
92 | unset($params['file']);
93 | return self::processFileUpload($file);
94 | }
95 |
96 | $mimeType = isset($params['mimeType'])
97 | ? $params['mimeType']['value']
98 | : false;
99 | unset($params['mimeType']);
100 |
101 | $data = isset($params['data'])
102 | ? $params['data']['value']
103 | : false;
104 | unset($params['data']);
105 |
106 | if (self::UPLOAD_RESUMABLE_TYPE == $uploadType) {
107 | $payload['content-type'] = $mimeType;
108 |
109 | } elseif (self::UPLOAD_MEDIA_TYPE == $uploadType) {
110 | // This is a simple media upload.
111 | $payload['content-type'] = $mimeType;
112 | $payload['postBody'] = $data;
113 | }
114 |
115 | elseif (self::UPLOAD_MULTIPART_TYPE == $uploadType) {
116 | // This is a multipart/related upload.
117 | $boundary = isset($params['boundary']['value']) ? $params['boundary']['value'] : mt_rand();
118 | $boundary = str_replace('"', '', $boundary);
119 | $payload['content-type'] = 'multipart/related; boundary=' . $boundary;
120 | $related = "--$boundary\r\n";
121 | $related .= "Content-Type: application/json; charset=UTF-8\r\n";
122 | $related .= "\r\n" . json_encode($meta) . "\r\n";
123 | $related .= "--$boundary\r\n";
124 | $related .= "Content-Type: $mimeType\r\n";
125 | $related .= "Content-Transfer-Encoding: base64\r\n";
126 | $related .= "\r\n" . base64_encode($data) . "\r\n";
127 | $related .= "--$boundary--";
128 | $payload['postBody'] = $related;
129 | }
130 |
131 | return $payload;
132 | }
133 |
134 | /**
135 | * Process standard file uploads.
136 | * @param $file
137 | * @internal param $fileName
138 | * @return array Inclues the processed file name.
139 | * @visible For testing.
140 | */
141 | public static function processFileUpload($file) {
142 | if (!$file) return array();
143 | if (substr($file, 0, 1) != '@') {
144 | $file = '@' . $file;
145 | }
146 |
147 | // This is a standard file upload with curl.
148 | return array('postBody' => array('file' => $file));
149 | }
150 |
151 | /**
152 | * Valid upload types:
153 | * - resumable (UPLOAD_RESUMABLE_TYPE)
154 | * - media (UPLOAD_MEDIA_TYPE)
155 | * - multipart (UPLOAD_MULTIPART_TYPE)
156 | * - none (false)
157 | * @param $meta
158 | * @param $payload
159 | * @param $params
160 | * @return bool|string
161 | */
162 | public static function getUploadType($meta, &$payload, &$params) {
163 | if (isset($params['mediaUpload'])
164 | && get_class($params['mediaUpload']['value']) == 'Google_MediaFileUpload') {
165 | $upload = $params['mediaUpload']['value'];
166 | unset($params['mediaUpload']);
167 | $payload['content-type'] = $upload->mimeType;
168 | if (isset($upload->resumable) && $upload->resumable) {
169 | return self::UPLOAD_RESUMABLE_TYPE;
170 | }
171 | }
172 |
173 | // Allow the developer to override the upload type.
174 | if (isset($params['uploadType'])) {
175 | return $params['uploadType']['value'];
176 | }
177 |
178 | $data = isset($params['data']['value'])
179 | ? $params['data']['value'] : false;
180 |
181 | if (false == $data && false == isset($params['file'])) {
182 | // No upload data available.
183 | return false;
184 | }
185 |
186 | if (isset($params['file'])) {
187 | return self::UPLOAD_MEDIA_TYPE;
188 | }
189 |
190 | if (false == $meta) {
191 | return self::UPLOAD_MEDIA_TYPE;
192 | }
193 |
194 | return self::UPLOAD_MULTIPART_TYPE;
195 | }
196 |
197 |
198 | public function nextChunk(Google_HttpRequest $req) {
199 | if (false == $this->resumeUri) {
200 | $this->resumeUri = $this->getResumeUri($req);
201 | }
202 |
203 | $data = substr($this->data, $this->progress, $this->chunkSize);
204 | $lastBytePos = $this->progress + strlen($data) - 1;
205 | $headers = array(
206 | 'content-range' => "bytes $this->progress-$lastBytePos/$this->size",
207 | 'content-type' => $req->getRequestHeader('content-type'),
208 | 'content-length' => $this->chunkSize,
209 | 'expect' => '',
210 | );
211 |
212 | $httpRequest = new Google_HttpRequest($this->resumeUri, 'PUT', $headers, $data);
213 | $response = Google_Client::$io->authenticatedRequest($httpRequest);
214 | $code = $response->getResponseHttpCode();
215 | if (308 == $code) {
216 | $range = explode('-', $response->getResponseHeader('range'));
217 | $this->progress = $range[1] + 1;
218 | return false;
219 | } else {
220 | return Google_REST::decodeHttpResponse($response);
221 | }
222 | }
223 |
224 | private function getResumeUri(Google_HttpRequest $httpRequest) {
225 | $result = null;
226 | $body = $httpRequest->getPostBody();
227 | if ($body) {
228 | $httpRequest->setRequestHeaders(array(
229 | 'content-type' => 'application/json; charset=UTF-8',
230 | 'content-length' => Google_Utils::getStrLen($body),
231 | 'x-upload-content-type' => $this->mimeType,
232 | 'expect' => '',
233 | ));
234 | }
235 |
236 | $response = Google_Client::$io->makeRequest($httpRequest);
237 | $location = $response->getResponseHeader('location');
238 | $code = $response->getResponseHttpCode();
239 | if (200 == $code && true == $location) {
240 | return $location;
241 | }
242 | throw new Google_Exception("Failed to start the resumable upload");
243 | }
244 | }
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/service/Google_Model.php:
--------------------------------------------------------------------------------
1 |
23 | *
24 | */
25 | class Google_Model {
26 | public function __construct( /* polymorphic */ ) {
27 | if (func_num_args() == 1 && is_array(func_get_arg(0))) {
28 | // Initialize the model with the array's contents.
29 | $array = func_get_arg(0);
30 | $this->mapTypes($array);
31 | }
32 | }
33 |
34 | /**
35 | * Initialize this object's properties from an array.
36 | *
37 | * @param array $array Used to seed this object's properties.
38 | * @return void
39 | */
40 | protected function mapTypes($array) {
41 | foreach ($array as $key => $val) {
42 | $this->$key = $val;
43 |
44 | $keyTypeName = "__$key" . 'Type';
45 | $keyDataType = "__$key" . 'DataType';
46 | if ($this->useObjects() && property_exists($this, $keyTypeName)) {
47 | if ($this->isAssociativeArray($val)) {
48 | if (isset($this->$keyDataType) && 'map' == $this->$keyDataType) {
49 | foreach($val as $arrayKey => $arrayItem) {
50 | $val[$arrayKey] = $this->createObjectFromName($keyTypeName, $arrayItem);
51 | }
52 | $this->$key = $val;
53 | } else {
54 | $this->$key = $this->createObjectFromName($keyTypeName, $val);
55 | }
56 | } else if (is_array($val)) {
57 | $arrayObject = array();
58 | foreach ($val as $arrayIndex => $arrayItem) {
59 | $arrayObject[$arrayIndex] = $this->createObjectFromName($keyTypeName, $arrayItem);
60 | }
61 | $this->$key = $arrayObject;
62 | }
63 | }
64 | }
65 | }
66 |
67 | /**
68 | * Returns true only if the array is associative.
69 | * @param array $array
70 | * @return bool True if the array is associative.
71 | */
72 | protected function isAssociativeArray($array) {
73 | if (!is_array($array)) {
74 | return false;
75 | }
76 | $keys = array_keys($array);
77 | foreach($keys as $key) {
78 | if (is_string($key)) {
79 | return true;
80 | }
81 | }
82 | return false;
83 | }
84 |
85 | /**
86 | * Given a variable name, discover its type.
87 | *
88 | * @param $name
89 | * @param $item
90 | * @return object The object from the item.
91 | */
92 | private function createObjectFromName($name, $item) {
93 | $type = $this->$name;
94 | return new $type($item);
95 | }
96 |
97 | protected function useObjects() {
98 | global $apiConfig;
99 | return (isset($apiConfig['use_objects']) && $apiConfig['use_objects']);
100 | }
101 |
102 | /**
103 | * Verify if $obj is an array.
104 | * @throws Google_Exception Thrown if $obj isn't an array.
105 | * @param array $obj Items that should be validated.
106 | * @param string $type Array items should be of this type.
107 | * @param string $method Method expecting an array as an argument.
108 | */
109 | public function assertIsArray($obj, $type, $method) {
110 | if ($obj && !is_array($obj)) {
111 | throw new Google_Exception("Incorrect parameter type passed to $method(), expected an"
112 | . " array containing items of type $type.");
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/service/Google_Service.php:
--------------------------------------------------------------------------------
1 |
24 | * @author Chirag Shah
25 | *
26 | */
27 | class Google_ServiceResource {
28 | // Valid query parameters that work, but don't appear in discovery.
29 | private $stackParameters = array(
30 | 'alt' => array('type' => 'string', 'location' => 'query'),
31 | 'boundary' => array('type' => 'string', 'location' => 'query'),
32 | 'fields' => array('type' => 'string', 'location' => 'query'),
33 | 'trace' => array('type' => 'string', 'location' => 'query'),
34 | 'userIp' => array('type' => 'string', 'location' => 'query'),
35 | 'userip' => array('type' => 'string', 'location' => 'query'),
36 | 'file' => array('type' => 'complex', 'location' => 'body'),
37 | 'data' => array('type' => 'string', 'location' => 'body'),
38 | 'mimeType' => array('type' => 'string', 'location' => 'header'),
39 | 'uploadType' => array('type' => 'string', 'location' => 'query'),
40 | 'mediaUpload' => array('type' => 'complex', 'location' => 'query'),
41 | );
42 |
43 | /** @var Google_Service $service */
44 | private $service;
45 |
46 | /** @var string $serviceName */
47 | private $serviceName;
48 |
49 | /** @var string $resourceName */
50 | private $resourceName;
51 |
52 | /** @var array $methods */
53 | private $methods;
54 |
55 | public function __construct($service, $serviceName, $resourceName, $resource) {
56 | $this->service = $service;
57 | $this->serviceName = $serviceName;
58 | $this->resourceName = $resourceName;
59 | $this->methods = isset($resource['methods']) ? $resource['methods'] : array($resourceName => $resource);
60 | }
61 |
62 | /**
63 | * @param $name
64 | * @param $arguments
65 | * @return Google_HttpRequest|array
66 | * @throws Google_Exception
67 | */
68 | public function __call($name, $arguments) {
69 | if (! isset($this->methods[$name])) {
70 | throw new Google_Exception("Unknown function: {$this->serviceName}->{$this->resourceName}->{$name}()");
71 | }
72 | $method = $this->methods[$name];
73 | $parameters = $arguments[0];
74 |
75 | // postBody is a special case since it's not defined in the discovery document as parameter, but we abuse the param entry for storing it
76 | $postBody = null;
77 | if (isset($parameters['postBody'])) {
78 | if (is_object($parameters['postBody'])) {
79 | $this->stripNull($parameters['postBody']);
80 | }
81 |
82 | // Some APIs require the postBody to be set under the data key.
83 | if (is_array($parameters['postBody']) && 'latitude' == $this->serviceName) {
84 | if (!isset($parameters['postBody']['data'])) {
85 | $rawBody = $parameters['postBody'];
86 | unset($parameters['postBody']);
87 | $parameters['postBody']['data'] = $rawBody;
88 | }
89 | }
90 |
91 | $postBody = is_array($parameters['postBody']) || is_object($parameters['postBody'])
92 | ? json_encode($parameters['postBody'])
93 | : $parameters['postBody'];
94 | unset($parameters['postBody']);
95 |
96 | if (isset($parameters['optParams'])) {
97 | $optParams = $parameters['optParams'];
98 | unset($parameters['optParams']);
99 | $parameters = array_merge($parameters, $optParams);
100 | }
101 | }
102 |
103 | if (!isset($method['parameters'])) {
104 | $method['parameters'] = array();
105 | }
106 |
107 | $method['parameters'] = array_merge($method['parameters'], $this->stackParameters);
108 | foreach ($parameters as $key => $val) {
109 | if ($key != 'postBody' && ! isset($method['parameters'][$key])) {
110 | throw new Google_Exception("($name) unknown parameter: '$key'");
111 | }
112 | }
113 | if (isset($method['parameters'])) {
114 | foreach ($method['parameters'] as $paramName => $paramSpec) {
115 | if (isset($paramSpec['required']) && $paramSpec['required'] && ! isset($parameters[$paramName])) {
116 | throw new Google_Exception("($name) missing required param: '$paramName'");
117 | }
118 | if (isset($parameters[$paramName])) {
119 | $value = $parameters[$paramName];
120 | $parameters[$paramName] = $paramSpec;
121 | $parameters[$paramName]['value'] = $value;
122 | unset($parameters[$paramName]['required']);
123 | } else {
124 | unset($parameters[$paramName]);
125 | }
126 | }
127 | }
128 |
129 | // Discovery v1.0 puts the canonical method id under the 'id' field.
130 | if (! isset($method['id'])) {
131 | $method['id'] = $method['rpcMethod'];
132 | }
133 |
134 | // Discovery v1.0 puts the canonical path under the 'path' field.
135 | if (! isset($method['path'])) {
136 | $method['path'] = $method['restPath'];
137 | }
138 |
139 | $servicePath = $this->service->servicePath;
140 |
141 | // Process Media Request
142 | $contentType = false;
143 | if (isset($method['mediaUpload'])) {
144 | $media = Google_MediaFileUpload::process($postBody, $parameters);
145 | if ($media) {
146 | $contentType = isset($media['content-type']) ? $media['content-type']: null;
147 | $postBody = isset($media['postBody']) ? $media['postBody'] : null;
148 | $servicePath = $method['mediaUpload']['protocols']['simple']['path'];
149 | $method['path'] = '';
150 | }
151 | }
152 |
153 | $url = Google_REST::createRequestUri($servicePath, $method['path'], $parameters);
154 | $httpRequest = new Google_HttpRequest($url, $method['httpMethod'], null, $postBody);
155 | if ($postBody) {
156 | $contentTypeHeader = array();
157 | if (isset($contentType) && $contentType) {
158 | $contentTypeHeader['content-type'] = $contentType;
159 | } else {
160 | $contentTypeHeader['content-type'] = 'application/json; charset=UTF-8';
161 | $contentTypeHeader['content-length'] = Google_Utils::getStrLen($postBody);
162 | }
163 | $httpRequest->setRequestHeaders($contentTypeHeader);
164 | }
165 |
166 | $httpRequest = Google_Client::$auth->sign($httpRequest);
167 | if (Google_Client::$useBatch) {
168 | return $httpRequest;
169 | }
170 |
171 | // Terminate immediatly if this is a resumable request.
172 | if (isset($parameters['uploadType']['value'])
173 | && 'resumable' == $parameters['uploadType']['value']) {
174 | return $httpRequest;
175 | }
176 |
177 | return Google_REST::execute($httpRequest);
178 | }
179 |
180 | public function useObjects() {
181 | global $apiConfig;
182 | return (isset($apiConfig['use_objects']) && $apiConfig['use_objects']);
183 | }
184 |
185 | protected function stripNull(&$o) {
186 | $o = (array) $o;
187 | foreach ($o as $k => $v) {
188 | if ($v === null || strstr($k, "\0*\0__")) {
189 | unset($o[$k]);
190 | }
191 | elseif (is_object($v) || is_array($v)) {
192 | $this->stripNull($o[$k]);
193 | }
194 | }
195 | }
196 | }
197 |
--------------------------------------------------------------------------------
/third_party/google-api-php-client/src/service/Google_Utils.php:
--------------------------------------------------------------------------------
1 |
23 | */
24 | class Google_Utils {
25 | public static function urlSafeB64Encode($data) {
26 | $b64 = base64_encode($data);
27 | $b64 = str_replace(array('+', '/', '\r', '\n', '='),
28 | array('-', '_'),
29 | $b64);
30 | return $b64;
31 | }
32 |
33 | public static function urlSafeB64Decode($b64) {
34 | $b64 = str_replace(array('-', '_'),
35 | array('+', '/'),
36 | $b64);
37 | return base64_decode($b64);
38 | }
39 |
40 | /**
41 | * Misc function used to count the number of bytes in a post body, in the world of multi-byte chars
42 | * and the unpredictability of strlen/mb_strlen/sizeof, this is the only way to do that in a sane
43 | * manner at the moment.
44 | *
45 | * This algorithm was originally developed for the
46 | * Solar Framework by Paul M. Jones
47 | *
48 | * @link http://solarphp.com/
49 | * @link http://svn.solarphp.com/core/trunk/Solar/Json.php
50 | * @link http://framework.zend.com/svn/framework/standard/trunk/library/Zend/Json/Decoder.php
51 | * @param string $str
52 | * @return int The number of bytes in a string.
53 | */
54 | static public function getStrLen($str) {
55 | $strlenVar = strlen($str);
56 | $d = $ret = 0;
57 | for ($count = 0; $count < $strlenVar; ++ $count) {
58 | $ordinalValue = ord($str{$ret});
59 | switch (true) {
60 | case (($ordinalValue >= 0x20) && ($ordinalValue <= 0x7F)):
61 | // characters U-00000000 - U-0000007F (same as ASCII)
62 | $ret ++;
63 | break;
64 |
65 | case (($ordinalValue & 0xE0) == 0xC0):
66 | // characters U-00000080 - U-000007FF, mask 110XXXXX
67 | // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
68 | $ret += 2;
69 | break;
70 |
71 | case (($ordinalValue & 0xF0) == 0xE0):
72 | // characters U-00000800 - U-0000FFFF, mask 1110XXXX
73 | // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
74 | $ret += 3;
75 | break;
76 |
77 | case (($ordinalValue & 0xF8) == 0xF0):
78 | // characters U-00010000 - U-001FFFFF, mask 11110XXX
79 | // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
80 | $ret += 4;
81 | break;
82 |
83 | case (($ordinalValue & 0xFC) == 0xF8):
84 | // characters U-00200000 - U-03FFFFFF, mask 111110XX
85 | // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
86 | $ret += 5;
87 | break;
88 |
89 | case (($ordinalValue & 0xFE) == 0xFC):
90 | // characters U-04000000 - U-7FFFFFFF, mask 1111110X
91 | // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
92 | $ret += 6;
93 | break;
94 | default:
95 | $ret ++;
96 | }
97 | }
98 | return $ret;
99 | }
100 |
101 | /**
102 | * Normalize all keys in an array to lower-case.
103 | * @param array $arr
104 | * @return array Normalized array.
105 | */
106 | public static function normalize($arr) {
107 | if (!is_array($arr)) {
108 | return array();
109 | }
110 |
111 | $normalized = array();
112 | foreach ($arr as $key => $val) {
113 | $normalized[strtolower($key)] = $val;
114 | }
115 | return $normalized;
116 | }
117 | }
--------------------------------------------------------------------------------