Social Share Icons & Social Share Buttons - Version 2.2.8

Version Description

  • Crashes/content disappearing fixed
Download this release

Release Info

Developer socialdude
Plugin Icon 128x128 Social Share Icons & Social Share Buttons
Version 2.2.8
Comparing to
See all releases

Code changes from version 2.2.7 to 2.2.8

helpers/sfsi_plus_OAuth.php CHANGED
@@ -3,37 +3,31 @@
3
 
4
  /* Generic exception class
5
  */
6
- if (!class_exists('OAuthException'))
7
- {
8
- class OAuthException extends Exception
9
- {
10
  // pass
11
  }
12
  }
13
 
14
- if (!class_exists('OAuthConsumer'))
15
- {
16
- class OAuthConsumer
17
- {
18
- public $key;
19
- public $secret;
20
-
21
- function __construct($key, $secret, $callback_url=NULL) {
22
- $this->key = $key;
23
- $this->secret = $secret;
24
- $this->callback_url = $callback_url;
25
- }
26
-
27
- function __toString() {
28
- return "OAuthConsumer[key=$this->key,secret=$this->secret]";
29
- }
30
  }
31
  }
32
 
33
- if (!class_exists('OAuthToken'))
34
- {
35
- class OAuthToken
36
- {
37
  // access tokens and request tokens
38
  public $key;
39
  public $secret;
@@ -42,8 +36,7 @@ if (!class_exists('OAuthToken'))
42
  * key = the token
43
  * secret = the token secret
44
  */
45
- function __construct($key, $secret)
46
- {
47
  $this->key = $key;
48
  $this->secret = $secret;
49
  }
@@ -52,60 +45,58 @@ if (!class_exists('OAuthToken'))
52
  * generates the basic string serialization of a token that a server
53
  * would respond to request_token and access_token calls with
54
  */
55
- function to_string()
56
- {
57
  return "oauth_token=" .
58
- OAuthUtil::urlencode_rfc3986($this->key) .
59
  "&oauth_token_secret=" .
60
- OAuthUtil::urlencode_rfc3986($this->secret);
61
  }
62
 
63
- function __toString()
64
- {
65
  return $this->to_string();
66
  }
67
  }
68
  }
 
69
  /**
70
  * A class for implementing a Signature Method
71
  * See section 9 ("Signing Requests") in the spec
72
  */
73
-
74
- if (!class_exists('OAuthSignatureMethod'))
75
- {
76
- abstract class OAuthSignatureMethod {
77
- /**
78
- * Needs to return the name of the Signature Method (ie HMAC-SHA1)
79
- * @return string
80
- */
81
- abstract public function get_name();
82
-
83
- /**
84
- * Build up the signature
85
- * NOTE: The output of this function MUST NOT be urlencoded.
86
- * the encoding is handled in OAuthRequest when the final
87
- * request is serialized
88
- * @param OAuthRequest $request
89
- * @param OAuthConsumer $consumer
90
- * @param OAuthToken $token
91
- * @return string
92
- */
93
- abstract public function build_signature($request, $consumer, $token);
94
-
95
- /**
96
- * Verifies that a given signature is correct
97
- * @param OAuthRequest $request
98
- * @param OAuthConsumer $consumer
99
- * @param OAuthToken $token
100
- * @param string $signature
101
- * @return bool
102
- */
103
- public function check_signature($request, $consumer, $token, $signature) {
104
  $built = $this->build_signature($request, $consumer, $token);
105
  return $built == $signature;
106
- }
107
  }
108
  }
 
109
  /**
110
  * The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104]
111
  * where the Signature Base String is the text and the key is the concatenated values (each first
@@ -113,31 +104,26 @@ if (!class_exists('OAuthSignatureMethod'))
113
  * character (ASCII code 38) even if empty.
114
  * - Chapter 9.2 ("HMAC-SHA1")
115
  */
116
-
117
- if (!class_exists('OAuthSignatureMethod_HMAC_SHA1'))
118
- {
119
- class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod
120
- {
121
- function get_name()
122
- {
123
- return "HMAC-SHA1";
124
- }
125
-
126
- public function build_signature($request, $consumer, $token)
127
- {
128
- $base_string = $request->get_signature_base_string();
129
- $request->base_string = $base_string;
130
-
131
- $key_parts = array(
132
- $consumer->secret,
133
- ($token) ? $token->secret : ""
134
- );
135
-
136
- $key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
137
- $key = implode('&', $key_parts);
138
-
139
- return base64_encode(hash_hmac('sha1', $base_string, $key, true));
140
- }
141
  }
142
  }
143
 
@@ -146,14 +132,12 @@ if (!class_exists('OAuthSignatureMethod_HMAC_SHA1'))
146
  * over a secure channel such as HTTPS. It does not use the Signature Base String.
147
  * - Chapter 9.4 ("PLAINTEXT")
148
  */
149
- if (!class_exists('OAuthSignatureMethod_PLAINTEXT'))
150
- {
151
- class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod
152
- {
153
  public function get_name() {
154
  return "PLAINTEXT";
155
  }
156
-
157
  /**
158
  * oauth_signature is set to the concatenated encoded values of the Consumer Secret and
159
  * Token Secret, separated by a '&' character (ASCII code 38), even if either secret is
@@ -168,8 +152,8 @@ if (!class_exists('OAuthSignatureMethod_PLAINTEXT'))
168
  $consumer->secret,
169
  ($token) ? $token->secret : ""
170
  );
171
-
172
- $key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
173
  $key = implode('&', $key_parts);
174
  $request->base_string = $key;
175
 
@@ -177,7 +161,6 @@ if (!class_exists('OAuthSignatureMethod_PLAINTEXT'))
177
  }
178
  }
179
  }
180
-
181
  /**
182
  * The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in
183
  * [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for
@@ -186,47 +169,45 @@ if (!class_exists('OAuthSignatureMethod_PLAINTEXT'))
186
  * specification.
187
  * - Chapter 9.3 ("RSA-SHA1")
188
  */
189
-
190
- if (!class_exists('OAuthSignatureMethod_RSA_SHA1'))
191
- {
192
- abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {
193
  public function get_name() {
194
  return "RSA-SHA1";
195
  }
196
-
197
- // Up to the SP to implement this lookup of keys. Possible ideas are:
198
- // (1) do a lookup in a table of trusted certs keyed off of consumer
199
- // (2) fetch via http using a url provided by the requester
200
- // (3) some sort of specific discovery code based on request
201
- //
202
- // Either way should return a string representation of the certificate
203
- protected abstract function fetch_public_cert(&$request);
204
-
205
- // Up to the SP to implement this lookup of keys. Possible ideas are:
206
- // (1) do a lookup in a table of trusted certs keyed off of consumer
207
- //
208
- // Either way should return a string representation of the certificate
209
- protected abstract function fetch_private_cert(&$request);
210
-
211
- public function build_signature($request, $consumer, $token) {
212
- $base_string = $request->get_signature_base_string();
213
- $request->base_string = $base_string;
214
-
215
- // Fetch the private key cert based on the request
216
- $cert = $this->fetch_private_cert($request);
217
-
218
- // Pull the private key ID from the certificate
219
- $privatekeyid = openssl_get_privatekey($cert);
220
-
221
- // Sign using the key
222
- $ok = openssl_sign($base_string, $signature, $privatekeyid);
223
-
224
- // Release the key resource
225
- openssl_free_key($privatekeyid);
226
-
227
- return base64_encode($signature);
228
- }
229
-
230
  public function check_signature($request, $consumer, $token, $signature) {
231
  $decoded_sig = base64_decode($signature);
232
 
@@ -249,10 +230,8 @@ if (!class_exists('OAuthSignatureMethod_RSA_SHA1'))
249
  }
250
  }
251
 
252
- if (!class_exists('OAuthRequest'))
253
- {
254
- class OAuthRequest
255
- {
256
  private $parameters;
257
  private $http_method;
258
  private $http_url;
@@ -263,242 +242,244 @@ if (!class_exists('OAuthRequest'))
263
 
264
  function __construct($http_method, $http_url, $parameters=NULL) {
265
  @$parameters or $parameters = array();
266
- $parameters = array_merge( OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters);
267
  $this->parameters = $parameters;
268
  $this->http_method = $http_method;
269
  $this->http_url = $http_url;
270
  }
271
- /**
272
- * attempt to build up a request from what was passed to the server
273
- */
274
- public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) {
275
- $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on")
276
- ? 'http'
277
- : 'https';
278
- @$http_url or $http_url = $scheme .
279
- '://' . $_SERVER['HTTP_HOST'] .
280
- ':' .
281
- $_SERVER['SERVER_PORT'] .
282
- $_SERVER['REQUEST_URI'];
283
- @$http_method or $http_method = $_SERVER['REQUEST_METHOD'];
284
-
285
- // We weren't handed any parameters, so let's find the ones relevant to
286
- // this request.
287
- // If you run XML-RPC or similar you should use this to provide your own
288
- // parsed parameter-list
289
- if (!$parameters) {
290
- // Find request headers
291
- $request_headers = OAuthUtil::get_headers();
292
-
293
- // Parse the query-string to find GET parameters
294
- $parameters = OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']);
295
-
296
- // It's a POST request of the proper content-type, so parse POST
297
- // parameters and add those overriding any duplicates from GET
298
- if ($http_method == "POST"
299
- && @strstr($request_headers["Content-Type"],
300
- "application/x-www-form-urlencoded")
301
- ) {
302
- $post_data = OAuthUtil::parse_parameters(
303
- file_get_contents(self::$POST_INPUT)
304
- );
305
- $parameters = array_merge($parameters, $post_data);
306
- }
307
-
308
- // We have a Authorization-header with OAuth data. Parse the header
309
- // and add those overriding any duplicates from GET or POST
310
- if (@substr($request_headers['Authorization'], 0, 6) == "OAuth ") {
311
- $header_parameters = OAuthUtil::split_header(
312
- $request_headers['Authorization']
313
- );
314
- $parameters = array_merge($parameters, $header_parameters);
315
- }
316
-
317
- }
318
-
319
- return new OAuthRequest($http_method, $http_url, $parameters);
320
- }
321
-
322
- /**
323
- * pretty much a helper function to set up the request
324
- */
325
- public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) {
326
- @$parameters or $parameters = array();
327
- $defaults = array("oauth_version" => OAuthRequest::$version,
328
- "oauth_nonce" => OAuthRequest::generate_nonce(),
329
- "oauth_timestamp" => OAuthRequest::generate_timestamp(),
330
- "oauth_consumer_key" => $consumer->key);
331
- if ($token)
332
- $defaults['oauth_token'] = $token->key;
333
-
334
- $parameters = array_merge($defaults, $parameters);
335
-
336
- return new OAuthRequest($http_method, $http_url, $parameters);
337
- }
338
-
339
- public function set_parameter($name, $value, $allow_duplicates = true) {
340
- if ($allow_duplicates && isset($this->parameters[$name])) {
341
- // We have already added parameter(s) with this name, so add to the list
342
- if (is_scalar($this->parameters[$name])) {
343
- // This is the first duplicate, so transform scalar (string)
344
- // into an array so we can add the duplicates
345
- $this->parameters[$name] = array($this->parameters[$name]);
346
- }
347
-
348
- $this->parameters[$name][] = $value;
349
- } else {
350
- $this->parameters[$name] = $value;
351
- }
352
- }
353
-
354
- public function get_parameter($name) {
355
- return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
356
- }
357
-
358
- public function get_parameters() {
359
- return $this->parameters;
360
- }
361
-
362
- public function unset_parameter($name) {
363
- unset($this->parameters[$name]);
364
- }
365
-
366
- /**
367
- * The request parameters, sorted and concatenated into a normalized string.
368
- * @return string
369
- */
370
- public function get_signable_parameters() {
371
- // Grab all parameters
372
- $params = $this->parameters;
373
-
374
- // Remove oauth_signature if present
375
- // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
376
- if (isset($params['oauth_signature'])) {
377
- unset($params['oauth_signature']);
378
- }
379
-
380
- return OAuthUtil::build_http_query($params);
381
- }
382
-
383
- /**
384
- * Returns the base string of this request
385
- *
386
- * The base string defined as the method, the url
387
- * and the parameters (normalized), each urlencoded
388
- * and the concated with &.
389
- */
390
- public function get_signature_base_string() {
391
- $parts = array(
392
- $this->get_normalized_http_method(),
393
- $this->get_normalized_http_url(),
394
- $this->get_signable_parameters()
395
- );
396
-
397
- $parts = OAuthUtil::urlencode_rfc3986($parts);
398
-
399
- return implode('&', $parts);
400
- }
401
-
402
- /**
403
- * just uppercases the http method
404
- */
405
- public function get_normalized_http_method() {
406
- return strtoupper($this->http_method);
407
- }
408
-
409
- /**
410
- * parses the url and rebuilds it to be
411
- * scheme://host/path
412
- */
413
- public function get_normalized_http_url() {
414
- $parts = parse_url($this->http_url);
415
-
416
- $port = @$parts['port'];
417
- $scheme = $parts['scheme'];
418
- $host = $parts['host'];
419
- $path = @$parts['path'];
420
-
421
- $port or $port = ($scheme == 'https') ? '443' : '80';
422
-
423
- if (($scheme == 'https' && $port != '443')
424
- || ($scheme == 'http' && $port != '80')) {
425
- $host = "$host:$port";
426
- }
427
- return "$scheme://$host$path";
428
- }
429
-
430
- /**
431
- * builds a url usable for a GET request
432
- */
433
- public function to_url() {
434
- $post_data = $this->to_postdata();
435
- $out = $this->get_normalized_http_url();
436
- if ($post_data) {
437
- $out .= '?'.$post_data;
438
- }
439
- return $out;
440
- }
441
-
442
- /**
443
- * builds the data one would send in a POST request
444
- */
445
- public function to_postdata() {
446
- return OAuthUtil::build_http_query($this->parameters);
447
- }
448
-
449
- /**
450
- * builds the Authorization: header
451
- */
452
- public function to_header($realm=null) {
453
- $first = true;
454
- if($realm) {
455
- $out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986($realm) . '"';
456
- $first = false;
457
- } else
458
- $out = 'Authorization: OAuth';
459
-
460
- $total = array();
461
- foreach ($this->parameters as $k => $v) {
462
- if (substr($k, 0, 5) != "oauth") continue;
463
- if (is_array($v)) {
464
- throw new OAuthException('Arrays not supported in headers');
465
- }
466
- $out .= ($first) ? ' ' : ',';
467
- $out .= OAuthUtil::urlencode_rfc3986($k) .
468
- '="' .
469
- OAuthUtil::urlencode_rfc3986($v) .
470
- '"';
471
- $first = false;
472
- }
473
- return $out;
474
- }
475
-
476
- public function __toString() {
477
- return $this->to_url();
478
- }
479
-
480
-
481
- public function sign_request($signature_method, $consumer, $token) {
482
- $this->set_parameter(
483
- "oauth_signature_method",
484
- $signature_method->get_name(),
485
- false
486
- );
487
- $signature = $this->build_signature($signature_method, $consumer, $token);
488
- $this->set_parameter("oauth_signature", $signature, false);
489
- }
490
-
491
- public function build_signature($signature_method, $consumer, $token) {
492
- $signature = $signature_method->build_signature($this, $consumer, $token);
493
- return $signature;
494
- }
495
-
496
- /**
497
- * util function: current timestamp
498
- */
499
- private static function generate_timestamp() {
500
- return time();
501
- }
 
 
502
 
503
  /**
504
  * util function: current nonce
@@ -512,402 +493,401 @@ if (!class_exists('OAuthRequest'))
512
  }
513
  }
514
 
515
- if (!class_exists('OAuthServer'))
516
- {
517
- class OAuthServer {
518
  protected $timestamp_threshold = 300; // in seconds, five minutes
519
  protected $version = '1.0'; // hi blaine
520
  protected $signature_methods = array();
521
 
522
  protected $data_store;
523
-
524
- function __construct($data_store) {
525
- $this->data_store = $data_store;
526
- }
527
-
528
- public function add_signature_method($signature_method) {
529
- $this->signature_methods[$signature_method->get_name()] =
530
- $signature_method;
531
- }
532
-
533
- // high level functions
534
-
535
- /**
536
- * process a request_token request
537
- * returns the request token on success
538
- */
539
- public function fetch_request_token(&$request) {
540
- $this->get_version($request);
541
-
542
- $consumer = $this->get_consumer($request);
543
-
544
- // no token required for the initial token request
545
- $token = NULL;
546
-
547
- $this->check_signature($request, $consumer, $token);
548
-
549
- // Rev A change
550
- $callback = $request->get_parameter('oauth_callback');
551
- $new_token = $this->data_store->new_request_token($consumer, $callback);
552
-
553
- return $new_token;
554
- }
555
-
556
- /**
557
- * process an access_token request
558
- * returns the access token on success
559
- */
560
- public function fetch_access_token(&$request) {
561
- $this->get_version($request);
562
-
563
- $consumer = $this->get_consumer($request);
564
-
565
- // requires authorized request token
566
- $token = $this->get_token($request, $consumer, "request");
567
-
568
- $this->check_signature($request, $consumer, $token);
569
-
570
- // Rev A change
571
- $verifier = $request->get_parameter('oauth_verifier');
572
- $new_token = $this->data_store->new_access_token($token, $consumer, $verifier);
573
-
574
- return $new_token;
575
- }
576
-
577
- /**
578
- * verify an api call, checks all the parameters
579
- */
580
- public function verify_request(&$request) {
581
- $this->get_version($request);
582
- $consumer = $this->get_consumer($request);
583
- $token = $this->get_token($request, $consumer, "access");
584
- $this->check_signature($request, $consumer, $token);
585
- return array($consumer, $token);
586
- }
587
-
588
- // Internals from here
589
- /**
590
- * version 1
591
- */
592
- private function get_version(&$request) {
593
- $version = $request->get_parameter("oauth_version");
594
- if (!$version) {
595
- // Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present.
596
- // Chapter 7.0 ("Accessing Protected Ressources")
597
- $version = '1.0';
598
- }
599
- if ($version !== $this->version) {
600
- throw new OAuthException("OAuth version '$version' not supported");
601
- }
602
- return $version;
603
- }
604
-
605
- /**
606
- * figure out the signature with some defaults
607
- */
608
- private function get_signature_method(&$request) {
609
- $signature_method =
610
- @$request->get_parameter("oauth_signature_method");
611
-
612
- if (!$signature_method) {
613
- // According to chapter 7 ("Accessing Protected Ressources") the signature-method
614
- // parameter is required, and we can't just fallback to PLAINTEXT
615
- throw new OAuthException('No signature method parameter. This parameter is required');
616
- }
617
-
618
- if (!in_array($signature_method,
619
- array_keys($this->signature_methods))) {
620
- throw new OAuthException(
621
- "Signature method '$signature_method' not supported " .
622
- "try one of the following: " .
623
- implode(", ", array_keys($this->signature_methods))
624
- );
625
- }
626
- return $this->signature_methods[$signature_method];
627
- }
628
-
629
- /**
630
- * try to find the consumer for the provided request's consumer key
631
- */
632
- private function get_consumer(&$request) {
633
- $consumer_key = @$request->get_parameter("oauth_consumer_key");
634
- if (!$consumer_key) {
635
- throw new OAuthException("Invalid consumer key");
636
- }
637
-
638
- $consumer = $this->data_store->lookup_consumer($consumer_key);
639
- if (!$consumer) {
640
- throw new OAuthException("Invalid consumer");
641
- }
642
-
643
- return $consumer;
644
- }
645
-
646
- /**
647
- * try to find the token for the provided request's token key
648
- */
649
- private function get_token(&$request, $consumer, $token_type="access") {
650
- $token_field = @$request->get_parameter('oauth_token');
651
- $token = $this->data_store->lookup_token(
652
- $consumer, $token_type, $token_field
653
- );
654
- if (!$token) {
655
- throw new OAuthException("Invalid $token_type token: $token_field");
656
- }
657
- return $token;
658
- }
659
-
660
- /**
661
- * all-in-one function to check the signature on a request
662
- * should guess the signature method appropriately
663
- */
664
- private function check_signature(&$request, $consumer, $token) {
665
- // this should probably be in a different method
666
- $timestamp = @$request->get_parameter('oauth_timestamp');
667
- $nonce = @$request->get_parameter('oauth_nonce');
668
-
669
- $this->check_timestamp($timestamp);
670
- $this->check_nonce($consumer, $token, $nonce, $timestamp);
671
-
672
- $signature_method = $this->get_signature_method($request);
673
-
674
- $signature = $request->get_parameter('oauth_signature');
675
- $valid_sig = $signature_method->check_signature(
676
- $request,
677
- $consumer,
678
- $token,
679
- $signature
680
- );
681
-
682
- if (!$valid_sig) {
683
- throw new OAuthException("Invalid signature");
684
- }
685
- }
686
-
687
- /**
688
- * check that the timestamp is new enough
689
- */
690
- private function check_timestamp($timestamp) {
691
- if( ! $timestamp )
692
- throw new OAuthException(
693
- 'Missing timestamp parameter. The parameter is required'
694
- );
695
-
696
- // verify that timestamp is recentish
697
- $now = time();
698
- if (abs($now - $timestamp) > $this->timestamp_threshold) {
699
- throw new OAuthException(
700
- "Expired timestamp, yours $timestamp, ours $now"
701
- );
702
- }
703
- }
704
-
705
- /**
706
- * check that the nonce is not repeated
707
- */
708
- private function check_nonce($consumer, $token, $nonce, $timestamp) {
709
- if( ! $nonce )
710
- throw new OAuthException(
711
- 'Missing nonce parameter. The parameter is required'
712
- );
713
-
714
- // verify that the nonce is uniqueish
715
- $found = $this->data_store->lookup_nonce(
716
- $consumer,
717
- $token,
718
- $nonce,
719
- $timestamp
720
- );
721
- if ($found) {
722
- throw new OAuthException("Nonce already used: $nonce");
723
- }
724
- }
725
- }
726
- }
727
- if (!class_exists('OAuthDataStore'))
728
- {
729
- class OAuthDataStore {
730
- function lookup_consumer($consumer_key) {
731
- // implement me
732
- }
733
-
734
- function lookup_token($consumer, $token_type, $token) {
735
- // implement me
736
- }
737
-
738
- function lookup_nonce($consumer, $token, $nonce, $timestamp) {
739
- // implement me
740
- }
741
-
742
- function new_request_token($consumer, $callback = null) {
743
- // return a new token attached to this consumer
744
- }
745
-
746
- function new_access_token($token, $consumer, $verifier = null) {
747
- // return a new access token attached to this consumer
748
- // for the user associated with this token if the request token
749
- // is authorized
750
- // should also invalidate the request token
751
- }
752
-
753
- }
754
  }
755
 
756
- if (!class_exists('OAuthUtil'))
757
- {
758
- class OAuthUtil {
759
- public static function urlencode_rfc3986($input) {
760
- if (is_array($input)) {
761
- return array_map(array('OAuthUtil', 'urlencode_rfc3986'), $input);
762
- } else if (is_scalar($input)) {
763
- return str_replace(
764
- '+',
765
- ' ',
766
- str_replace('%7E', '~', rawurlencode($input))
767
- );
768
- } else {
769
- return '';
770
- }
 
 
 
 
 
 
 
 
 
 
 
771
  }
772
-
773
-
774
- // This decode function isn't taking into consideration the above
775
- // modifications to the encoding process. However, this method doesn't
776
- // seem to be used anywhere so leaving it as is.
777
- public static function urldecode_rfc3986($string) {
778
- return urldecode($string);
779
- }
780
-
781
- // Utility function for turning the Authorization: header into
782
- // parameters, has to do some unescaping
783
- // Can filter out any non-oauth parameters if needed (default behaviour)
784
- public static function split_header($header, $only_allow_oauth_parameters = true) {
785
- $pattern = '/(([-_a-z]*)=("([^"]*)"|([^,]*)),?)/';
786
- $offset = 0;
787
- $params = array();
788
- while (preg_match($pattern, $header, $matches, PREG_OFFSET_CAPTURE, $offset) > 0) {
789
- $match = $matches[0];
790
- $header_name = $matches[2][0];
791
- $header_content = (isset($matches[5])) ? $matches[5][0] : $matches[4][0];
792
- if (preg_match('/^oauth_/', $header_name) || !$only_allow_oauth_parameters) {
793
- $params[$header_name] = OAuthUtil::urldecode_rfc3986($header_content);
794
- }
795
- $offset = $match[1] + strlen($match[0]);
796
- }
797
-
798
- if (isset($params['realm'])) {
799
- unset($params['realm']);
800
- }
801
 
802
- return $params;
803
- }
804
-
805
- // helper to try to sort out headers for people who aren't running apache
806
- public static function get_headers() {
807
- if (function_exists('apache_request_headers')) {
808
- // we need this to get the actual Authorization: header
809
- // because apache tends to tell us it doesn't exist
810
- $headers = apache_request_headers();
811
-
812
- // sanitize the output of apache_request_headers because
813
- // we always want the keys to be Cased-Like-This and arh()
814
- // returns the headers in the same case as they are in the
815
- // request
816
- $out = array();
817
- foreach( $headers AS $key => $value ) {
818
- $key = str_replace(
819
- " ",
820
- "-",
821
- ucwords(strtolower(str_replace("-", " ", $key)))
822
- );
823
- $out[$key] = $value;
824
- }
825
- } else {
826
- // otherwise we don't have apache and are just going to have to hope
827
- // that $_SERVER actually contains what we need
828
- $out = array();
829
- if( isset($_SERVER['CONTENT_TYPE']) )
830
- $out['Content-Type'] = $_SERVER['CONTENT_TYPE'];
831
- if( isset($_ENV['CONTENT_TYPE']) )
832
- $out['Content-Type'] = $_ENV['CONTENT_TYPE'];
833
-
834
- foreach ($_SERVER as $key => $value) {
835
- if (substr($key, 0, 5) == "HTTP_") {
836
- // this is chaos, basically it is just there to capitalize the first
837
- // letter of every word that is not an initial HTTP and strip HTTP
838
- // code from przemek
839
- $key = str_replace(
840
- " ",
841
- "-",
842
- ucwords(strtolower(str_replace("_", " ", substr($key, 5))))
843
- );
844
- $out[$key] = $value;
845
- }
846
- }
847
- }
848
- return $out;
849
- }
850
-
851
- // This function takes a input like a=b&a=c&d=e and returns the parsed
852
- // parameters like this
853
- // array('a' => array('b','c'), 'd' => 'e')
854
- public static function parse_parameters( $input ) {
855
- if (!isset($input) || !$input) return array();
856
-
857
- $pairs = explode('&', $input);
858
-
859
- $parsed_parameters = array();
860
- foreach ($pairs as $pair) {
861
- $split = explode('=', $pair, 2);
862
- $parameter = OAuthUtil::urldecode_rfc3986($split[0]);
863
- $value = isset($split[1]) ? OAuthUtil::urldecode_rfc3986($split[1]) : '';
864
-
865
- if (isset($parsed_parameters[$parameter])) {
866
- // We have already recieved parameter(s) with this name, so add to the list
867
- // of parameters with this name
868
-
869
- if (is_scalar($parsed_parameters[$parameter])) {
870
- // This is the first duplicate, so transform scalar (string) into an array
871
- // so we can add the duplicates
872
- $parsed_parameters[$parameter] = array($parsed_parameters[$parameter]);
873
- }
874
-
875
- $parsed_parameters[$parameter][] = $value;
876
- } else {
877
- $parsed_parameters[$parameter] = $value;
878
- }
879
- }
880
- return $parsed_parameters;
881
- }
882
-
883
- public static function build_http_query($params) {
884
- if (!$params) return '';
885
-
886
- // Urlencode both keys and values
887
- $keys = OAuthUtil::urlencode_rfc3986(array_keys($params));
888
- $values = OAuthUtil::urlencode_rfc3986(array_values($params));
889
- $params = array_combine($keys, $values);
890
-
891
- // Parameters are sorted by name, using lexicographical byte value ordering.
892
- // Ref: Spec: 9.1.1 (1)
893
- uksort($params, 'strcmp');
894
-
895
- $pairs = array();
896
- foreach ($params as $parameter => $value) {
897
- if (is_array($value)) {
898
- // If two or more parameters share the same name, they are sorted by their value
899
- // Ref: Spec: 9.1.1 (1)
900
- natsort($value);
901
- foreach ($value as $duplicate_value) {
902
- $pairs[] = $parameter . '=' . $duplicate_value;
903
- }
904
- } else {
905
- $pairs[] = $parameter . '=' . $value;
906
- }
907
- }
908
- // For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61)
909
- // Each name-value pair is separated by an '&' character (ASCII code 38)
910
- return implode('&', $pairs);
911
- }
912
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
913
  }
3
 
4
  /* Generic exception class
5
  */
6
+ if (!class_exists('Plus_OAuthException')) {
7
+ class Plus_OAuthException extends Exception {
 
 
8
  // pass
9
  }
10
  }
11
 
12
+ if (!class_exists('Plus_OAuthConsumer')) {
13
+ class Plus_OAuthConsumer {
14
+ public $key;
15
+ public $secret;
16
+
17
+ function __construct($key, $secret, $callback_url=NULL) {
18
+ $this->key = $key;
19
+ $this->secret = $secret;
20
+ $this->callback_url = $callback_url;
21
+ }
22
+
23
+ function __toString() {
24
+ return "Plus_OAuthConsumer[key=$this->key,secret=$this->secret]";
25
+ }
 
 
26
  }
27
  }
28
 
29
+ if (!class_exists('Plus_OAuthToken')) {
30
+ class Plus_OAuthToken {
 
 
31
  // access tokens and request tokens
32
  public $key;
33
  public $secret;
36
  * key = the token
37
  * secret = the token secret
38
  */
39
+ function __construct($key, $secret) {
 
40
  $this->key = $key;
41
  $this->secret = $secret;
42
  }
45
  * generates the basic string serialization of a token that a server
46
  * would respond to request_token and access_token calls with
47
  */
48
+ function to_string() {
 
49
  return "oauth_token=" .
50
+ Plus_OAuthUtil::urlencode_rfc3986($this->key) .
51
  "&oauth_token_secret=" .
52
+ Plus_OAuthUtil::urlencode_rfc3986($this->secret);
53
  }
54
 
55
+ function __toString() {
 
56
  return $this->to_string();
57
  }
58
  }
59
  }
60
+
61
  /**
62
  * A class for implementing a Signature Method
63
  * See section 9 ("Signing Requests") in the spec
64
  */
65
+ if (!class_exists('Plus_OAuthSignatureMethod')) {
66
+ abstract class Plus_OAuthSignatureMethod {
67
+ /**
68
+ * Needs to return the name of the Signature Method (ie HMAC-SHA1)
69
+ * @return string
70
+ */
71
+ abstract public function get_name();
72
+
73
+ /**
74
+ * Build up the signature
75
+ * NOTE: The output of this function MUST NOT be urlencoded.
76
+ * the encoding is handled in OAuthRequest when the final
77
+ * request is serialized
78
+ * @param OAuthRequest $request
79
+ * @param OAuthConsumer $consumer
80
+ * @param OAuthToken $token
81
+ * @return string
82
+ */
83
+ abstract public function build_signature($request, $consumer, $token);
84
+
85
+ /**
86
+ * Verifies that a given signature is correct
87
+ * @param OAuthRequest $request
88
+ * @param OAuthConsumer $consumer
89
+ * @param OAuthToken $token
90
+ * @param string $signature
91
+ * @return bool
92
+ */
93
+ public function check_signature($request, $consumer, $token, $signature) {
 
 
94
  $built = $this->build_signature($request, $consumer, $token);
95
  return $built == $signature;
96
+ }
97
  }
98
  }
99
+
100
  /**
101
  * The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104]
102
  * where the Signature Base String is the text and the key is the concatenated values (each first
104
  * character (ASCII code 38) even if empty.
105
  * - Chapter 9.2 ("HMAC-SHA1")
106
  */
107
+ if (!class_exists('Plus_OAuthSignatureMethod_HMAC_SHA1')) {
108
+ class Plus_OAuthSignatureMethod_HMAC_SHA1 extends Plus_OAuthSignatureMethod {
109
+ function get_name() {
110
+ return "HMAC-SHA1";
111
+ }
112
+
113
+ public function build_signature($request, $consumer, $token) {
114
+ $base_string = $request->get_signature_base_string();
115
+ $request->base_string = $base_string;
116
+
117
+ $key_parts = array(
118
+ $consumer->secret,
119
+ ($token) ? $token->secret : ""
120
+ );
121
+
122
+ $key_parts = Plus_OAuthUtil::urlencode_rfc3986($key_parts);
123
+ $key = implode('&', $key_parts);
124
+
125
+ return base64_encode(hash_hmac('sha1', $base_string, $key, true));
126
+ }
 
 
 
 
 
127
  }
128
  }
129
 
132
  * over a secure channel such as HTTPS. It does not use the Signature Base String.
133
  * - Chapter 9.4 ("PLAINTEXT")
134
  */
135
+ if (!class_exists('Plus_OAuthSignatureMethod_PLAINTEXT')) {
136
+ class Plus_OAuthSignatureMethod_PLAINTEXT extends Plus_OAuthSignatureMethod {
 
 
137
  public function get_name() {
138
  return "PLAINTEXT";
139
  }
140
+
141
  /**
142
  * oauth_signature is set to the concatenated encoded values of the Consumer Secret and
143
  * Token Secret, separated by a '&' character (ASCII code 38), even if either secret is
152
  $consumer->secret,
153
  ($token) ? $token->secret : ""
154
  );
155
+
156
+ $key_parts = Plus_OAuthUtil::urlencode_rfc3986($key_parts);
157
  $key = implode('&', $key_parts);
158
  $request->base_string = $key;
159
 
161
  }
162
  }
163
  }
 
164
  /**
165
  * The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in
166
  * [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for
169
  * specification.
170
  * - Chapter 9.3 ("RSA-SHA1")
171
  */
172
+ if (!class_exists('Plus_OAuthSignatureMethod_RSA_SHA1')) {
173
+ abstract class Plus_OAuthSignatureMethod_RSA_SHA1 extends Plus_OAuthSignatureMethod {
 
 
174
  public function get_name() {
175
  return "RSA-SHA1";
176
  }
177
+
178
+ // Up to the SP to implement this lookup of keys. Possible ideas are:
179
+ // (1) do a lookup in a table of trusted certs keyed off of consumer
180
+ // (2) fetch via http using a url provided by the requester
181
+ // (3) some sort of specific discovery code based on request
182
+ //
183
+ // Either way should return a string representation of the certificate
184
+ protected abstract function fetch_public_cert(&$request);
185
+
186
+ // Up to the SP to implement this lookup of keys. Possible ideas are:
187
+ // (1) do a lookup in a table of trusted certs keyed off of consumer
188
+ //
189
+ // Either way should return a string representation of the certificate
190
+ protected abstract function fetch_private_cert(&$request);
191
+
192
+ public function build_signature($request, $consumer, $token) {
193
+ $base_string = $request->get_signature_base_string();
194
+ $request->base_string = $base_string;
195
+
196
+ // Fetch the private key cert based on the request
197
+ $cert = $this->fetch_private_cert($request);
198
+
199
+ // Pull the private key ID from the certificate
200
+ $privatekeyid = openssl_get_privatekey($cert);
201
+
202
+ // Sign using the key
203
+ $ok = openssl_sign($base_string, $signature, $privatekeyid);
204
+
205
+ // Release the key resource
206
+ openssl_free_key($privatekeyid);
207
+
208
+ return base64_encode($signature);
209
+ }
210
+
211
  public function check_signature($request, $consumer, $token, $signature) {
212
  $decoded_sig = base64_decode($signature);
213
 
230
  }
231
  }
232
 
233
+ if (!class_exists('Plus_OAuthRequest')) {
234
+ class Plus_OAuthRequest {
 
 
235
  private $parameters;
236
  private $http_method;
237
  private $http_url;
242
 
243
  function __construct($http_method, $http_url, $parameters=NULL) {
244
  @$parameters or $parameters = array();
245
+ $parameters = array_merge( Plus_OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters);
246
  $this->parameters = $parameters;
247
  $this->http_method = $http_method;
248
  $this->http_url = $http_url;
249
  }
250
+
251
+
252
+ /**
253
+ * attempt to build up a request from what was passed to the server
254
+ */
255
+ public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) {
256
+ $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on")
257
+ ? 'http'
258
+ : 'https';
259
+ @$http_url or $http_url = $scheme .
260
+ '://' . $_SERVER['HTTP_HOST'] .
261
+ ':' .
262
+ $_SERVER['SERVER_PORT'] .
263
+ $_SERVER['REQUEST_URI'];
264
+ @$http_method or $http_method = $_SERVER['REQUEST_METHOD'];
265
+
266
+ // We weren't handed any parameters, so let's find the ones relevant to
267
+ // this request.
268
+ // If you run XML-RPC or similar you should use this to provide your own
269
+ // parsed parameter-list
270
+ if (!$parameters) {
271
+ // Find request headers
272
+ $request_headers = Plus_OAuthUtil::get_headers();
273
+
274
+ // Parse the query-string to find GET parameters
275
+ $parameters = Plus_OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']);
276
+
277
+ // It's a POST request of the proper content-type, so parse POST
278
+ // parameters and add those overriding any duplicates from GET
279
+ if ($http_method == "POST"
280
+ && @strstr($request_headers["Content-Type"],
281
+ "application/x-www-form-urlencoded")
282
+ ) {
283
+ $post_data = Plus_OAuthUtil::parse_parameters(
284
+ file_get_contents(self::$POST_INPUT)
285
+ );
286
+ $parameters = array_merge($parameters, $post_data);
287
+ }
288
+
289
+ // We have a Authorization-header with OAuth data. Parse the header
290
+ // and add those overriding any duplicates from GET or POST
291
+ if (@substr($request_headers['Authorization'], 0, 6) == "OAuth ") {
292
+ $header_parameters = Plus_OAuthUtil::split_header(
293
+ $request_headers['Authorization']
294
+ );
295
+ $parameters = array_merge($parameters, $header_parameters);
296
+ }
297
+
298
+ }
299
+
300
+ return new Plus_OAuthRequest($http_method, $http_url, $parameters);
301
+ }
302
+
303
+ /**
304
+ * pretty much a helper function to set up the request
305
+ */
306
+ public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) {
307
+ @$parameters or $parameters = array();
308
+ $defaults = array("oauth_version" => Plus_OAuthRequest::$version,
309
+ "oauth_nonce" => Plus_OAuthRequest::generate_nonce(),
310
+ "oauth_timestamp" => Plus_OAuthRequest::generate_timestamp(),
311
+ "oauth_consumer_key" => $consumer->key);
312
+ if ($token)
313
+ $defaults['oauth_token'] = $token->key;
314
+
315
+ $parameters = array_merge($defaults, $parameters);
316
+
317
+ return new Plus_OAuthRequest($http_method, $http_url, $parameters);
318
+ }
319
+
320
+ public function set_parameter($name, $value, $allow_duplicates = true) {
321
+ if ($allow_duplicates && isset($this->parameters[$name])) {
322
+ // We have already added parameter(s) with this name, so add to the list
323
+ if (is_scalar($this->parameters[$name])) {
324
+ // This is the first duplicate, so transform scalar (string)
325
+ // into an array so we can add the duplicates
326
+ $this->parameters[$name] = array($this->parameters[$name]);
327
+ }
328
+
329
+ $this->parameters[$name][] = $value;
330
+ } else {
331
+ $this->parameters[$name] = $value;
332
+ }
333
+ }
334
+
335
+ public function get_parameter($name) {
336
+ return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
337
+ }
338
+
339
+ public function get_parameters() {
340
+ return $this->parameters;
341
+ }
342
+
343
+ public function unset_parameter($name) {
344
+ unset($this->parameters[$name]);
345
+ }
346
+
347
+ /**
348
+ * The request parameters, sorted and concatenated into a normalized string.
349
+ * @return string
350
+ */
351
+ public function get_signable_parameters() {
352
+ // Grab all parameters
353
+ $params = $this->parameters;
354
+
355
+ // Remove oauth_signature if present
356
+ // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
357
+ if (isset($params['oauth_signature'])) {
358
+ unset($params['oauth_signature']);
359
+ }
360
+
361
+ return Plus_OAuthUtil::build_http_query($params);
362
+ }
363
+
364
+ /**
365
+ * Returns the base string of this request
366
+ *
367
+ * The base string defined as the method, the url
368
+ * and the parameters (normalized), each urlencoded
369
+ * and the concated with &.
370
+ */
371
+ public function get_signature_base_string() {
372
+ $parts = array(
373
+ $this->get_normalized_http_method(),
374
+ $this->get_normalized_http_url(),
375
+ $this->get_signable_parameters()
376
+ );
377
+
378
+ $parts = Plus_OAuthUtil::urlencode_rfc3986($parts);
379
+
380
+ return implode('&', $parts);
381
+ }
382
+
383
+ /**
384
+ * just uppercases the http method
385
+ */
386
+ public function get_normalized_http_method() {
387
+ return strtoupper($this->http_method);
388
+ }
389
+
390
+ /**
391
+ * parses the url and rebuilds it to be
392
+ * scheme://host/path
393
+ */
394
+ public function get_normalized_http_url() {
395
+ $parts = parse_url($this->http_url);
396
+
397
+ $port = @$parts['port'];
398
+ $scheme = $parts['scheme'];
399
+ $host = $parts['host'];
400
+ $path = @$parts['path'];
401
+
402
+ $port or $port = ($scheme == 'https') ? '443' : '80';
403
+
404
+ if (($scheme == 'https' && $port != '443')
405
+ || ($scheme == 'http' && $port != '80')) {
406
+ $host = "$host:$port";
407
+ }
408
+ return "$scheme://$host$path";
409
+ }
410
+
411
+ /**
412
+ * builds a url usable for a GET request
413
+ */
414
+ public function to_url() {
415
+ $post_data = $this->to_postdata();
416
+ $out = $this->get_normalized_http_url();
417
+ if ($post_data) {
418
+ $out .= '?'.$post_data;
419
+ }
420
+ return $out;
421
+ }
422
+
423
+ /**
424
+ * builds the data one would send in a POST request
425
+ */
426
+ public function to_postdata() {
427
+ return Plus_OAuthUtil::build_http_query($this->parameters);
428
+ }
429
+
430
+ /**
431
+ * builds the Authorization: header
432
+ */
433
+ public function to_header($realm=null) {
434
+ $first = true;
435
+ if($realm) {
436
+ $out = 'Authorization: OAuth realm="' . Plus_OAuthUtil::urlencode_rfc3986($realm) . '"';
437
+ $first = false;
438
+ } else
439
+ $out = 'Authorization: OAuth';
440
+
441
+ $total = array();
442
+ foreach ($this->parameters as $k => $v) {
443
+ if (substr($k, 0, 5) != "oauth") continue;
444
+ if (is_array($v)) {
445
+ throw new Plus_OAuthException('Arrays not supported in headers');
446
+ }
447
+ $out .= ($first) ? ' ' : ',';
448
+ $out .= Plus_OAuthUtil::urlencode_rfc3986($k) .
449
+ '="' .
450
+ Plus_OAuthUtil::urlencode_rfc3986($v) .
451
+ '"';
452
+ $first = false;
453
+ }
454
+ return $out;
455
+ }
456
+
457
+ public function __toString() {
458
+ return $this->to_url();
459
+ }
460
+
461
+
462
+ public function sign_request($signature_method, $consumer, $token) {
463
+ $this->set_parameter(
464
+ "oauth_signature_method",
465
+ $signature_method->get_name(),
466
+ false
467
+ );
468
+ $signature = $this->build_signature($signature_method, $consumer, $token);
469
+ $this->set_parameter("oauth_signature", $signature, false);
470
+ }
471
+
472
+ public function build_signature($signature_method, $consumer, $token) {
473
+ $signature = $signature_method->build_signature($this, $consumer, $token);
474
+ return $signature;
475
+ }
476
+
477
+ /**
478
+ * util function: current timestamp
479
+ */
480
+ private static function generate_timestamp() {
481
+ return time();
482
+ }
483
 
484
  /**
485
  * util function: current nonce
493
  }
494
  }
495
 
496
+ if (!class_exists('Plus_OAuthServer')) {
497
+ class Plus_OAuthServer {
 
498
  protected $timestamp_threshold = 300; // in seconds, five minutes
499
  protected $version = '1.0'; // hi blaine
500
  protected $signature_methods = array();
501
 
502
  protected $data_store;
503
+
504
+ function __construct($data_store) {
505
+ $this->data_store = $data_store;
506
+ }
507
+
508
+ public function add_signature_method($signature_method) {
509
+ $this->signature_methods[$signature_method->get_name()] =
510
+ $signature_method;
511
+ }
512
+
513
+ // high level functions
514
+
515
+ /**
516
+ * process a request_token request
517
+ * returns the request token on success
518
+ */
519
+ public function fetch_request_token(&$request) {
520
+ $this->get_version($request);
521
+
522
+ $consumer = $this->get_consumer($request);
523
+
524
+ // no token required for the initial token request
525
+ $token = NULL;
526
+
527
+ $this->check_signature($request, $consumer, $token);
528
+
529
+ // Rev A change
530
+ $callback = $request->get_parameter('oauth_callback');
531
+ $new_token = $this->data_store->new_request_token($consumer, $callback);
532
+
533
+ return $new_token;
534
+ }
535
+
536
+ /**
537
+ * process an access_token request
538
+ * returns the access token on success
539
+ */
540
+ public function fetch_access_token(&$request) {
541
+ $this->get_version($request);
542
+
543
+ $consumer = $this->get_consumer($request);
544
+
545
+ // requires authorized request token
546
+ $token = $this->get_token($request, $consumer, "request");
547
+
548
+ $this->check_signature($request, $consumer, $token);
549
+
550
+ // Rev A change
551
+ $verifier = $request->get_parameter('oauth_verifier');
552
+ $new_token = $this->data_store->new_access_token($token, $consumer, $verifier);
553
+
554
+ return $new_token;
555
+ }
556
+
557
+ /**
558
+ * verify an api call, checks all the parameters
559
+ */
560
+ public function verify_request(&$request) {
561
+ $this->get_version($request);
562
+ $consumer = $this->get_consumer($request);
563
+ $token = $this->get_token($request, $consumer, "access");
564
+ $this->check_signature($request, $consumer, $token);
565
+ return array($consumer, $token);
566
+ }
567
+
568
+ // Internals from here
569
+ /**
570
+ * version 1
571
+ */
572
+ private function get_version(&$request) {
573
+ $version = $request->get_parameter("oauth_version");
574
+ if (!$version) {
575
+ // Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present.
576
+ // Chapter 7.0 ("Accessing Protected Ressources")
577
+ $version = '1.0';
578
+ }
579
+ if ($version !== $this->version) {
580
+ throw new Plus_OAuthException("OAuth version '$version' not supported");
581
+ }
582
+ return $version;
583
+ }
584
+
585
+ /**
586
+ * figure out the signature with some defaults
587
+ */
588
+ private function get_signature_method(&$request) {
589
+ $signature_method =
590
+ @$request->get_parameter("oauth_signature_method");
591
+
592
+ if (!$signature_method) {
593
+ // According to chapter 7 ("Accessing Protected Ressources") the signature-method
594
+ // parameter is required, and we can't just fallback to PLAINTEXT
595
+ throw new Plus_OAuthException('No signature method parameter. This parameter is required');
596
+ }
597
+
598
+ if (!in_array($signature_method,
599
+ array_keys($this->signature_methods))) {
600
+ throw new Plus_OAuthException(
601
+ "Signature method '$signature_method' not supported " .
602
+ "try one of the following: " .
603
+ implode(", ", array_keys($this->signature_methods))
604
+ );
605
+ }
606
+ return $this->signature_methods[$signature_method];
607
+ }
608
+
609
+ /**
610
+ * try to find the consumer for the provided request's consumer key
611
+ */
612
+ private function get_consumer(&$request) {
613
+ $consumer_key = @$request->get_parameter("oauth_consumer_key");
614
+ if (!$consumer_key) {
615
+ throw new Plus_OAuthException("Invalid consumer key");
616
+ }
617
+
618
+ $consumer = $this->data_store->lookup_consumer($consumer_key);
619
+ if (!$consumer) {
620
+ throw new Plus_OAuthException("Invalid consumer");
621
+ }
622
+
623
+ return $consumer;
624
+ }
625
+
626
+ /**
627
+ * try to find the token for the provided request's token key
628
+ */
629
+ private function get_token(&$request, $consumer, $token_type="access") {
630
+ $token_field = @$request->get_parameter('oauth_token');
631
+ $token = $this->data_store->lookup_token(
632
+ $consumer, $token_type, $token_field
633
+ );
634
+ if (!$token) {
635
+ throw new Plus_OAuthException("Invalid $token_type token: $token_field");
636
+ }
637
+ return $token;
638
+ }
639
+
640
+ /**
641
+ * all-in-one function to check the signature on a request
642
+ * should guess the signature method appropriately
643
+ */
644
+ private function check_signature(&$request, $consumer, $token) {
645
+ // this should probably be in a different method
646
+ $timestamp = @$request->get_parameter('oauth_timestamp');
647
+ $nonce = @$request->get_parameter('oauth_nonce');
648
+
649
+ $this->check_timestamp($timestamp);
650
+ $this->check_nonce($consumer, $token, $nonce, $timestamp);
651
+
652
+ $signature_method = $this->get_signature_method($request);
653
+
654
+ $signature = $request->get_parameter('oauth_signature');
655
+ $valid_sig = $signature_method->check_signature(
656
+ $request,
657
+ $consumer,
658
+ $token,
659
+ $signature
660
+ );
661
+
662
+ if (!$valid_sig) {
663
+ throw new Plus_OAuthException("Invalid signature");
664
+ }
665
+ }
666
+
667
+ /**
668
+ * check that the timestamp is new enough
669
+ */
670
+ private function check_timestamp($timestamp) {
671
+ if( ! $timestamp )
672
+ throw new Plus_OAuthException(
673
+ 'Missing timestamp parameter. The parameter is required'
674
+ );
675
+
676
+ // verify that timestamp is recentish
677
+ $now = time();
678
+ if (abs($now - $timestamp) > $this->timestamp_threshold) {
679
+ throw new Plus_OAuthException(
680
+ "Expired timestamp, yours $timestamp, ours $now"
681
+ );
682
+ }
683
+ }
684
+
685
+ /**
686
+ * check that the nonce is not repeated
687
+ */
688
+ private function check_nonce($consumer, $token, $nonce, $timestamp) {
689
+ if( ! $nonce )
690
+ throw new Plus_OAuthException(
691
+ 'Missing nonce parameter. The parameter is required'
692
+ );
693
+
694
+ // verify that the nonce is uniqueish
695
+ $found = $this->data_store->lookup_nonce(
696
+ $consumer,
697
+ $token,
698
+ $nonce,
699
+ $timestamp
700
+ );
701
+ if ($found) {
702
+ throw new Plus_OAuthException("Nonce already used: $nonce");
703
+ }
704
+ }
705
+
706
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
707
  }
708
 
709
+ if (!class_exists('Plus_OAuthDataStore')) {
710
+ class Plus_OAuthDataStore {
711
+ function lookup_consumer($consumer_key) {
712
+ // implement me
713
+ }
714
+
715
+ function lookup_token($consumer, $token_type, $token) {
716
+ // implement me
717
+ }
718
+
719
+ function lookup_nonce($consumer, $token, $nonce, $timestamp) {
720
+ // implement me
721
+ }
722
+
723
+ function new_request_token($consumer, $callback = null) {
724
+ // return a new token attached to this consumer
725
+ }
726
+
727
+ function new_access_token($token, $consumer, $verifier = null) {
728
+ // return a new access token attached to this consumer
729
+ // for the user associated with this token if the request token
730
+ // is authorized
731
+ // should also invalidate the request token
732
+ }
733
+
734
+ }
735
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
736
 
737
+ if (!class_exists('Plus_OAuthUtil')) {
738
+ class Plus_OAuthUtil {
739
+ public static function urlencode_rfc3986($input) {
740
+ if (is_array($input)) {
741
+ return array_map(array('Plus_OAuthUtil', 'urlencode_rfc3986'), $input);
742
+ } else if (is_scalar($input)) {
743
+ return str_replace(
744
+ '+',
745
+ ' ',
746
+ str_replace('%7E', '~', rawurlencode($input))
747
+ );
748
+ } else {
749
+ return '';
750
+ }
751
+ }
752
+
753
+
754
+ // This decode function isn't taking into consideration the above
755
+ // modifications to the encoding process. However, this method doesn't
756
+ // seem to be used anywhere so leaving it as is.
757
+ public static function urldecode_rfc3986($string) {
758
+ return urldecode($string);
759
+ }
760
+
761
+ // Utility function for turning the Authorization: header into
762
+ // parameters, has to do some unescaping
763
+ // Can filter out any non-oauth parameters if needed (default behaviour)
764
+ public static function split_header($header, $only_allow_oauth_parameters = true) {
765
+ $pattern = '/(([-_a-z]*)=("([^"]*)"|([^,]*)),?)/';
766
+ $offset = 0;
767
+ $params = array();
768
+ while (preg_match($pattern, $header, $matches, PREG_OFFSET_CAPTURE, $offset) > 0) {
769
+ $match = $matches[0];
770
+ $header_name = $matches[2][0];
771
+ $header_content = (isset($matches[5])) ? $matches[5][0] : $matches[4][0];
772
+ if (preg_match('/^oauth_/', $header_name) || !$only_allow_oauth_parameters) {
773
+ $params[$header_name] = Plus_OAuthUtil::urldecode_rfc3986($header_content);
774
+ }
775
+ $offset = $match[1] + strlen($match[0]);
776
+ }
777
+
778
+ if (isset($params['realm'])) {
779
+ unset($params['realm']);
780
+ }
781
+
782
+ return $params;
783
+ }
784
+
785
+ // helper to try to sort out headers for people who aren't running apache
786
+ public static function get_headers() {
787
+ if (function_exists('apache_request_headers')) {
788
+ // we need this to get the actual Authorization: header
789
+ // because apache tends to tell us it doesn't exist
790
+ $headers = apache_request_headers();
791
+
792
+ // sanitize the output of apache_request_headers because
793
+ // we always want the keys to be Cased-Like-This and arh()
794
+ // returns the headers in the same case as they are in the
795
+ // request
796
+ $out = array();
797
+ foreach( $headers AS $key => $value ) {
798
+ $key = str_replace(
799
+ " ",
800
+ "-",
801
+ ucwords(strtolower(str_replace("-", " ", $key)))
802
+ );
803
+ $out[$key] = $value;
804
+ }
805
+ } else {
806
+ // otherwise we don't have apache and are just going to have to hope
807
+ // that $_SERVER actually contains what we need
808
+ $out = array();
809
+ if( isset($_SERVER['CONTENT_TYPE']) )
810
+ $out['Content-Type'] = $_SERVER['CONTENT_TYPE'];
811
+ if( isset($_ENV['CONTENT_TYPE']) )
812
+ $out['Content-Type'] = $_ENV['CONTENT_TYPE'];
813
+
814
+ foreach ($_SERVER as $key => $value) {
815
+ if (substr($key, 0, 5) == "HTTP_") {
816
+ // this is chaos, basically it is just there to capitalize the first
817
+ // letter of every word that is not an initial HTTP and strip HTTP
818
+ // code from przemek
819
+ $key = str_replace(
820
+ " ",
821
+ "-",
822
+ ucwords(strtolower(str_replace("_", " ", substr($key, 5))))
823
+ );
824
+ $out[$key] = $value;
825
+ }
826
+ }
827
+ }
828
+ return $out;
829
+ }
830
+
831
+ // This function takes a input like a=b&a=c&d=e and returns the parsed
832
+ // parameters like this
833
+ // array('a' => array('b','c'), 'd' => 'e')
834
+ public static function parse_parameters( $input ) {
835
+ if (!isset($input) || !$input) return array();
836
+
837
+ $pairs = explode('&', $input);
838
+
839
+ $parsed_parameters = array();
840
+ foreach ($pairs as $pair) {
841
+ $split = explode('=', $pair, 2);
842
+ $parameter = Plus_OAuthUtil::urldecode_rfc3986($split[0]);
843
+ $value = isset($split[1]) ? Plus_OAuthUtil::urldecode_rfc3986($split[1]) : '';
844
+
845
+ if (isset($parsed_parameters[$parameter])) {
846
+ // We have already recieved parameter(s) with this name, so add to the list
847
+ // of parameters with this name
848
+
849
+ if (is_scalar($parsed_parameters[$parameter])) {
850
+ // This is the first duplicate, so transform scalar (string) into an array
851
+ // so we can add the duplicates
852
+ $parsed_parameters[$parameter] = array($parsed_parameters[$parameter]);
853
+ }
854
+
855
+ $parsed_parameters[$parameter][] = $value;
856
+ } else {
857
+ $parsed_parameters[$parameter] = $value;
858
+ }
859
+ }
860
+ return $parsed_parameters;
861
+ }
862
+
863
+ public static function build_http_query($params) {
864
+ if (!$params) return '';
865
+
866
+ // Urlencode both keys and values
867
+ $keys = Plus_OAuthUtil::urlencode_rfc3986(array_keys($params));
868
+ $values = Plus_OAuthUtil::urlencode_rfc3986(array_values($params));
869
+ $params = array_combine($keys, $values);
870
+
871
+ // Parameters are sorted by name, using lexicographical byte value ordering.
872
+ // Ref: Spec: 9.1.1 (1)
873
+ uksort($params, 'strcmp');
874
+
875
+ $pairs = array();
876
+ foreach ($params as $parameter => $value) {
877
+ if (is_array($value)) {
878
+ // If two or more parameters share the same name, they are sorted by their value
879
+ // Ref: Spec: 9.1.1 (1)
880
+ natsort($value);
881
+ foreach ($value as $duplicate_value) {
882
+ $pairs[] = $parameter . '=' . $duplicate_value;
883
+ }
884
+ } else {
885
+ $pairs[] = $parameter . '=' . $value;
886
+ }
887
+ }
888
+ // For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61)
889
+ // Each name-value pair is separated by an '&' character (ASCII code 38)
890
+ return implode('&', $pairs);
891
+ }
892
+ }
893
  }
libs/sfsi_install_uninstall.php CHANGED
@@ -12,7 +12,7 @@ function sfsi_plus_update_plugin()
12
  }
13
 
14
  //Install version
15
- update_option("sfsi_plus_pluginVersion", "2.27");
16
 
17
  /*show notification*/
18
  if(!get_option('sfsi_plus_show_notification'))
12
  }
13
 
14
  //Install version
15
+ update_option("sfsi_plus_pluginVersion", "2.28");
16
 
17
  /*show notification*/
18
  if(!get_option('sfsi_plus_show_notification'))
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=seb.r
4
  Tags: social media, social media icons, social media buttons, social media sharing, floating social media, social media icon, social media button, sharing icons, sharing, sharing buttons, social media widget, socialmedia, social media pop-up, social, social icons, icon, icons, buttons, facebook icon, twitter icon, instagram, instagram icon, counter, facebook, facebook like, like, tweet, tweet button, buttons, tweet icon, youtube, youtube icon, linkedin, linkedin icon, logos, follow, social profiles, social media accounts, social share
5
  Requires at least: 3.0
6
  Tested up to: 4.4.2
7
- Stable tag: 2.2.7
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -75,6 +75,9 @@ Please check out the FAQ on http://ultimatelysocial.com
75
 
76
  == Changelog ==
77
 
 
 
 
78
  = 2.2.7 =
79
  * Overkill declaration in the CSS fixed
80
  * Custom icons can now have mailto:-functionality
@@ -188,5 +191,5 @@ Please check out the FAQ on http://ultimatelysocial.com
188
 
189
  == Upgrade Notice ==
190
 
191
- = 2.2.7 =
192
  * Please upgrade if you faced issues before or want to use different languages
4
  Tags: social media, social media icons, social media buttons, social media sharing, floating social media, social media icon, social media button, sharing icons, sharing, sharing buttons, social media widget, socialmedia, social media pop-up, social, social icons, icon, icons, buttons, facebook icon, twitter icon, instagram, instagram icon, counter, facebook, facebook like, like, tweet, tweet button, buttons, tweet icon, youtube, youtube icon, linkedin, linkedin icon, logos, follow, social profiles, social media accounts, social share
5
  Requires at least: 3.0
6
  Tested up to: 4.4.2
7
+ Stable tag: 2.2.8
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
75
 
76
  == Changelog ==
77
 
78
+ = 2.2.8 =
79
+ * Crashes/content disappearing fixed
80
+
81
  = 2.2.7 =
82
  * Overkill declaration in the CSS fixed
83
  * Custom icons can now have mailto:-functionality
191
 
192
  == Upgrade Notice ==
193
 
194
+ = 2.2.8 =
195
  * Please upgrade if you faced issues before or want to use different languages
ultimate_social_media_icons.php CHANGED
@@ -6,7 +6,7 @@ Description: The best social media plugin on the market. And 100% FREE. Allows y
6
  Author: UltimatelySocial
7
  Text Domain: ultimate-social-media-plus
8
  Author URI: http://ultimatelysocial.com
9
- Version: 2.2.7
10
  License: GPLv2
11
  */
12
 
@@ -35,7 +35,7 @@ register_deactivation_hook(__FILE__, 'sfsi_plus_deactivate_plugin');
35
  register_uninstall_hook(__FILE__, 'sfsi_plus_Unistall_plugin');
36
 
37
  /*Plugin version setup*/
38
- if(!get_option('sfsi_plus_pluginVersion') || get_option('sfsi_plus_pluginVersion') < 2.27)
39
  {
40
  add_action("init", "sfsi_plus_update_plugin");
41
  }
6
  Author: UltimatelySocial
7
  Text Domain: ultimate-social-media-plus
8
  Author URI: http://ultimatelysocial.com
9
+ Version: 2.2.8
10
  License: GPLv2
11
  */
12
 
35
  register_uninstall_hook(__FILE__, 'sfsi_plus_Unistall_plugin');
36
 
37
  /*Plugin version setup*/
38
+ if(!get_option('sfsi_plus_pluginVersion') || get_option('sfsi_plus_pluginVersion') < 2.28)
39
  {
40
  add_action("init", "sfsi_plus_update_plugin");
41
  }
views/sfsi_option_view9.php CHANGED
@@ -4,10 +4,12 @@
4
  $feedId = get_option('sfsi_plus_feed_id',false);
5
  ?>
6
  <div class="tab9">
7
-
 
 
8
  <p>
9
  <?php _e('In addition to the email- or follow-icon you can also show a subscription form which maximizes chances that people subscribe to your site. To get access to the emails who subscribe, please', 'ultimate-social-media-plus'); ?>
10
- <a href="http://www.specificfeeds.com/<?php echo $feedId; ?>?getParam=feeds_claims" target="_blank">
11
  <?php _e('claim your feed.','ultimate-social-media-plus'); ?>
12
  </a>
13
  </p>
4
  $feedId = get_option('sfsi_plus_feed_id',false);
5
  ?>
6
  <div class="tab9">
7
+ <?php
8
+ $connectToFeed = "http://www.specificfeeds.com/?".base64_encode("userprofile=wordpress&feed_id=".$feedId);
9
+ ?>
10
  <p>
11
  <?php _e('In addition to the email- or follow-icon you can also show a subscription form which maximizes chances that people subscribe to your site. To get access to the emails who subscribe, please', 'ultimate-social-media-plus'); ?>
12
+ <a target="_new" href="<?php echo $connectToFeed; ?>">
13
  <?php _e('claim your feed.','ultimate-social-media-plus'); ?>
14
  </a>
15
  </p>