Skip to content
This repository

adding Context to CakeSocket #334

Closed
wants to merge 5 commits into from

3 participants

pocketcrocodile José Lorenzo Rodríguez Mark Story
pocketcrocodile

#2270 adding Context to CakeSocket and HTTP Socket. Changing CakeSocket
from fsockopen to stream_socket_client allows giving the connection an
context. the default behavior is: if the connection is secure we get
the certificate, parse it and deliver it with the http-response object.

pocketcrocodile #2270 adding Context to CakeSocket
#2270 adding Context to CakeSocket and HTTP Socket. Changing CakeSocket
from fsockopen to stream_socket_client allows giving the connection an
context. the default behavior is: if the connection is secure we get
the certificate, parse it and deliver it with the http-response object.
954ac7f
pocketcrocodile pocketcrocodile closed this
pocketcrocodile

#2270 adding Context to CakeSocket and HTTP Socket. Changing CakeSocket
from fsockopen to stream_socket_client allows giving the connection an
context. the default behavior is: if the connection is secure we get
the certificate, parse it and deliver it with the http-response object.

José Lorenzo Rodríguez
Owner

I'm not sure what is this trying to fix. using the CakeSocket class with the ssl:// protocol already works. can you explain this a little bit more?

pocketcrocodile

of course cake socket works with ssl, but it does not give the context back (esp. the ssl cert for checking if we are communicating with the right server). the change is, we now get the certificate back and deliver it in the resonse object to the application.

Mark Story
Owner

Shouldn't you be checking for the openssl_x509_export function before trying to use it? Not all installations have openssl installed.

pocketcrocodile

good point. i'll check this.

pocketcrocodile pocketcrocodile reopened this
pocketcrocodile

i am getting crazy, but github did not let me update my request.

Mark Story
Owner

You should be able to push to the original branch you pushed to. Github will automatically update the pull request.

pocketcrocodile undo last Change 68b3365
pocketcrocodile check openssl
check if openssl is installed by if php know openssl functions.
1516f9a
pocketcrocodile

don't know why the change did not appear here, but now it does (and also my earlier changes).

Mark Story markstory commented on the diff
lib/Cake/Network/Http/HttpSocket.php
((15 lines not shown))
  747
+		if ($context !== null && is_array($context) &&!empty($context)){
  748
+			$this->config['request']['context'] = set::merge($this->config['request']['context'], $context);
  749
+		}
  750
+	}
  751
+
  752
+/**
  753
+ * checking Fingerprint and setting Fingerprint to contextarray.
  754
+ *
  755
+ * @param string fingerprint fingerprint the certificate should have
  756
+ * return bool
  757
+ * @access protected
  758
+ */
  759
+
  760
+	
  761
+	public function checkFingerprint($fingerprint){
  762
+		if (!isset($this->request['context']['ssl']['peer_certificate']))
1
Mark Story Owner

Missing braces.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Mark Story markstory commented on the diff
lib/Cake/Network/Http/HttpSocket.php
@@ -373,6 +383,10 @@ public function request($request = array()) {
373 383
 		}
374 384
 		$responseClass = $this->responseClass;
375 385
 		$this->response = new $responseClass($response);
  386
+
  387
+		if (!empty($context) && isset($context['ssl']['peer_certificate']))
1
Mark Story Owner

Missing braces.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Mark Story markstory commented on the diff
lib/Cake/Network/Http/HttpResponse.php
@@ -419,6 +426,21 @@ public function offsetGet($offset) {
419 426
 		return null;
420 427
 	}
421 428
 
  429
+	public function setContext($context){
  430
+		if (get_resource_type($context) === "OpenSSL X.509" && function_exists(openssl_x509_export)){
  431
+			if (!isset($context))
1
Mark Story Owner

Missing braces.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Mark Story
Owner

Closing in favor of #947

Mark Story markstory closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 5 unique commits by 1 author.

Nov 24, 2011
pocketcrocodile #2270 adding Context to CakeSocket
#2270 adding Context to CakeSocket and HTTP Socket. Changing CakeSocket
from fsockopen to stream_socket_client allows giving the connection an
context. the default behavior is: if the connection is secure we get
the certificate, parse it and deliver it with the http-response object.
954ac7f
Nov 25, 2011
pocketcrocodile checking if openssl is installed 4304116
Nov 28, 2011
pocketcrocodile undo last Change 68b3365
pocketcrocodile check openssl
check if openssl is installed by if php know openssl functions.
1516f9a
Feb 25, 2012
pocketcrocodile added missing branches
added missing branches
edec0bc
This page is out of date. Refresh to see the latest.
21  lib/Cake/Network/CakeSocket.php
@@ -104,12 +104,17 @@ public function connect() {
104 104
 			$scheme = 'ssl://';
105 105
 		}
106 106
 
107  
-		if ($this->config['persistent'] == true) {
108  
-			$this->connection = @pfsockopen($scheme.$this->config['host'], $this->config['port'], $errNum, $errStr, $this->config['timeout']);
  107
+		if (!empty($this->config['request']['context'])){
  108
+			$mycontext = stream_context_create($this->config['request']['context']);
109 109
 		} else {
110  
-			$this->connection = @fsockopen($scheme.$this->config['host'], $this->config['port'], $errNum, $errStr, $this->config['timeout']);
  110
+			$mycontext = stream_context_create();
111 111
 		}
112 112
 
  113
+		if ($this->config['persistent'] == true) {
  114
+			$this->connection = @stream_socket_client($scheme.$this->config['host'].':'. $this->config['port'], &$errNum, &$errStr, $this->config['timeout'], STREAM_CLIENT_PERSISTENT, $mycontext);
  115
+		} else {
  116
+			$this->connection = @stream_socket_client($scheme.$this->config['host'].':'. $this->config['port'], &$errNum, &$errStr, $this->config['timeout'], STREAM_CLIENT_CONNECT, $mycontext);
  117
+		}
113 118
 		if (!empty($errNum) || !empty($errStr)) {
114 119
 			$this->setLastError($errNum, $errStr);
115 120
 			throw new SocketException($errStr, $errNum);
@@ -228,6 +233,16 @@ public function read($length = 1024) {
228 233
 		}
229 234
 		return false;
230 235
 	}
  236
+/**
  237
+ * get Connection Context.
  238
+ *
  239
+ * @return context Array
  240
+ */
  241
+	public function getContext(){
  242
+		return stream_context_get_options($this->connection);
  243
+	}
  244
+
  245
+
231 246
 
232 247
 /**
233 248
  * Disconnect the socket from the current connection.
23  lib/Cake/Network/Http/HttpResponse.php
@@ -53,6 +53,13 @@ class HttpResponse implements ArrayAccess {
53 53
 	public $httpVersion = 'HTTP/1.1';
54 54
 
55 55
 /**
  56
+ * context
  57
+ *
  58
+ * @var array
  59
+ */
  60
+	public $context = array();
  61
+
  62
+/**
56 63
  * Response code
57 64
  *
58 65
  * @var integer
@@ -419,6 +426,22 @@ public function offsetGet($offset) {
419 426
 		return null;
420 427
 	}
421 428
 
  429
+	public function setContext($context){
  430
+		if (get_resource_type($context) === "OpenSSL X.509" && function_exists(openssl_x509_export)){
  431
+			if (!isset($context)){
  432
+				return false;
  433
+			}
  434
+			openssl_x509_export($context, &$certstring);
  435
+			$certstring = str_replace('-----BEGIN CERTIFICATE-----', '', $certstring);
  436
+			$certstring = str_replace('-----END CERTIFICATE-----', '', $certstring);
  437
+			$this->context = openssl_x509_parse($context);
  438
+			$this->context['fingerprint']['sha1'] = strtoupper(sha1($certstring));
  439
+			$this->context['fingerprint']['md5'] = strtoupper(md5($certstring));
  440
+		} else {
  441
+			return false;
  442
+		}
  443
+	}
  444
+
422 445
 /**
423 446
  * ArrayAccess - 0ffset Set
424 447
  *
58  lib/Cake/Network/Http/HttpSocket.php
@@ -64,7 +64,8 @@ class HttpSocket extends CakeSocket {
64 64
 		),
65 65
 		'raw' => null,
66 66
 		'redirect' => false,
67  
-		'cookies' => array()
  67
+		'cookies' => array(),
  68
+		'context' => array()
68 69
 	);
69 70
 
70 71
 /**
@@ -99,7 +100,8 @@ class HttpSocket extends CakeSocket {
99 100
 				'port' => 80
100 101
 			),
101 102
 			'redirect' => false,
102  
-			'cookies' => array()
  103
+			'cookies' => array(),
  104
+			'context' => array()
103 105
 		)
104 106
 	);
105 107
 
@@ -325,6 +327,8 @@ public function request($request = array()) {
325 327
 			return false;
326 328
 		}
327 329
 
  330
+		$this->_configContext($this->request['context']);
  331
+
328 332
 		$this->request['raw'] = '';
329 333
 		if ($this->request['line'] !== false) {
330 334
 			$this->request['raw'] = $this->request['line'];
@@ -362,10 +366,16 @@ public function request($request = array()) {
362 366
 			}
363 367
 		}
364 368
 
  369
+		if (isset($this->request['context'])){
  370
+			$context = $this->getContext();
  371
+		}
  372
+
  373
+
365 374
 		if ($connectionType === 'close') {
366 375
 			$this->disconnect();
367 376
 		}
368 377
 
  378
+
369 379
 		list($plugin, $responseClass) = pluginSplit($this->responseClass, true);
370 380
 		App::uses($this->responseClass, $plugin . 'Network/Http');
371 381
 		if (!class_exists($responseClass)) {
@@ -373,6 +383,10 @@ public function request($request = array()) {
373 383
 		}
374 384
 		$responseClass = $this->responseClass;
375 385
 		$this->response = new $responseClass($response);
  386
+
  387
+		if (!empty($context) && isset($context['ssl']['peer_certificate'])){
  388
+			$this->response->setContext($context['ssl']['peer_certificate']);
  389
+		}
376 390
 		if (!empty($this->response->cookies)) {
377 391
 			if (!isset($this->config['request']['cookies'][$Host])) {
378 392
 				$this->config['request']['cookies'][$Host] = array();
@@ -719,6 +733,46 @@ protected function _parseUri($uri = null, $base = array()) {
719 733
 	}
720 734
 
721 735
 /**
  736
+ * Sets context-parameter
  737
+ *
  738
+ * @param array $context Context, See http://www.php.net/manual/de/context.php
  739
+ * @access protected
  740
+ */
  741
+	private function _configContext($context = null){
  742
+		if ($this->config['request']['uri']['scheme'] == 'https'){
  743
+			$this->config['request']['context']['ssl'] = array(
  744
+				'capture_peer_cert' => true,
  745
+			);
  746
+		}
  747
+		if ($context !== null && is_array($context) &&!empty($context)){
  748
+			$this->config['request']['context'] = set::merge($this->config['request']['context'], $context);
  749
+		}
  750
+	}
  751
+
  752
+/**
  753
+ * checking Fingerprint and setting Fingerprint to contextarray.
  754
+ *
  755
+ * @param string fingerprint fingerprint the certificate should have
  756
+ * return bool
  757
+ * @access protected
  758
+ */
  759
+
  760
+	
  761
+	public function checkFingerprint($fingerprint){
  762
+		if (!isset($this->request['context']['ssl']['peer_certificate'])){
  763
+			return false;
  764
+		}
  765
+		openssl_x509_export($this->request['context']['ssl']['peer_certificate'], &$certstring);
  766
+		$certstring = str_replace('-----BEGIN CERTIFICATE-----', '', $certstring);
  767
+		$certstring = str_replace('-----END CERTIFICATE-----', '', $certstring);
  768
+		$certstring = base64_decode($certstring);
  769
+		$this->request['context']['ssl']['fingerprint']['sha1'] = strtoupper(sha1($certstring));
  770
+		return trim($fingerprint) == $request['context']['ssl']['fingerprint']['sha1'];
  771
+	}
  772
+
  773
+
  774
+
  775
+/**
722 776
  * This function can be thought of as a reverse to PHP5's http_build_query(). It takes a given query string and turns it into an array and
723 777
  * supports nesting by using the php bracket syntax. So this menas you can parse queries like:
724 778
  *
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.