1 <?php
2
3 namespace Mypos\IPC;
4
5 6 7
8 abstract class Base{
9
10 11 12
13 private $cnf;
14
15 16 17
18 private $params = array();
19
20 21 22
23 protected $outputFormat = Defines::COMMUNICATION_FORMAT_JSON;
24
25 26 27 28
29 protected function getCnf(){
30 return $this->cnf;
31 }
32
33 34 35 36
37 protected function setCnf(Config $cnf){
38 $this->cnf = $cnf;
39 }
40
41 42 43 44
45 function getOutputFormat(){
46 return $this->outputFormat;
47 }
48
49 50 51 52
53 function setOutputFormat($outputFormat){
54 $this->outputFormat = $outputFormat;
55 }
56
57 58 59 60 61
62 protected function _addPostParam($paramName, $paramValue, $encrypt=false){
63 $this->params[$paramName] = $encrypt?$this->_encryptData($paramValue):Helper::escape(Helper::unescape($paramValue));
64 }
65
66 67 68
69 protected function _processHtmlPost(){
70
71 $this->params['Signature'] = $this->_createSignature();
72
73 $c = '';
74 $c = '<body onload="document.ipcForm.submit();">';
75 $c .= '<form id="ipcForm" name="ipcForm" action="' . $this->getCnf()->getIpcURL() . '" method="post">';
76 foreach($this->params as $k => $v){
77 $c .= "<input type=\"hidden\" name=\"" . $k . "\" value=\"" . $v . "\" />\n";
78 }
79 $c .= '</form></body>';
80 echo $c;
81 exit;
82 }
83
84 85 86 87 88
89 protected function _processPost(){
90 $this->params['Signature'] = $this->_createSignature();
91 $cont = array();
92 $url = parse_url($this->getCnf()->getIpcURL());
93 if(!isset($url['port'])){
94 switch($url['scheme']){
95 case 'https':
96 $url['port'] = 443;
97 $ssl = "ssl://";
98 break;
99 case 'http':
100 $url['port'] = 80;
101 $ssl = "";
102 break;
103 }
104 }
105 $postData = http_build_query($this->params);
106 $fp = @fsockopen($ssl . $url['host'], $url['port'], $errno, $errstr, 10);
107 if(!$fp){
108 throw new IPC_Exception('Error connectiong IPC URL');
109 }else{
110 $eol = "\r\n";
111 $path = $url['path'] . (!(empty($url['query'])) ? ('?' . $url['query']) : '');
112 fputs($fp, "POST " . $path . " HTTP/1.1" . $eol);
113 fputs($fp, "Host: " . $url['host'] . $eol);
114 fputs($fp, "Content-type: application/x-www-form-urlencoded" . $eol);
115 fputs($fp, "Content-length: " . strlen($postData) . $eol);
116 fputs($fp, "Connection: close" . $eol . $eol);
117 fputs($fp, $postData . $eol . $eol);
118
119 $result = '';
120 while(!feof($fp)){
121 $result .= @fgets($fp, 1024);
122 }
123 fclose($fp);
124 $result = explode($eol . $eol, $result, 2);
125 $header = isset($result[0]) ? $result[0] : '';
126 $cont = isset($result[1]) ? $result[1] : '';
127
128
129 if(!empty($cont) && strpos($header, 'Transfer-Encoding: chunked') !== false){
130 $check = $this->_httpChunkedDecode($cont);
131 if($check){
132 $cont = $check;
133 }
134 }
135 if($cont){
136 $cont = trim($cont);
137 }
138
139 return Response::getInstance($this->getCnf(), $cont, $this->outputFormat);
140 }
141 }
142
143 144 145 146 147
148 private function _httpChunkedDecode($chunk){
149 $pos = 0;
150 $len = strlen($chunk);
151 $dechunk = null;
152
153 while(($pos < $len) && ($chunkLenHex = substr($chunk, $pos, ($newlineAt = strpos($chunk, "\n", $pos + 1)) - $pos))){
154 if(!$this->_is_hex($chunkLenHex)){
155 return false;
156 }
157
158 $pos = $newlineAt + 1;
159 $chunkLen = hexdec(rtrim($chunkLenHex, "\r\n"));
160 $dechunk .= substr($chunk, $pos, $chunkLen);
161 $pos = strpos($chunk, "\n", $pos + $chunkLen) + 1;
162 }
163 return $dechunk;
164 }
165
166 167 168 169 170 171
172 private function _is_hex($hex){
173
174 $hex = strtolower(trim(ltrim($hex, "0")));
175 if(empty($hex)){
176 $hex = 0;
177 };
178 $dec = hexdec($hex);
179 return ($hex == dechex($dec));
180 }
181
182 183 184 185
186 private function _createSignature(){
187 $params = $this->params;
188 foreach($params as $k => $v){
189 $params[$k] = Helper::unescape($v);
190 }
191 $concData = base64_encode(implode('-', $params));
192 $privKey = openssl_get_privatekey($this->getCnf()->getPrivateKey());
193 openssl_sign($concData, $signature, $privKey, Defines::SIGNATURE_ALGO);
194 return base64_encode($signature);
195 }
196
197
198 199 200 201
202 private function _encryptData($data){
203 openssl_public_encrypt($data, $crypted, $this->getCnf()->getEncryptPublicKey(), Defines::ENCRYPT_PADDING);
204 return base64_encode($crypted);
205 }
206
207 208 209 210 211 212 213
214 public static function isValidSignature($data, $signature, $pubKey){
215 $pubKeyId = openssl_get_publickey($pubKey);
216 $res = openssl_verify($data, base64_decode($signature), $pubKeyId, Defines::SIGNATURE_ALGO);
217 openssl_free_key($pubKeyId);
218 if($res != 1){
219 return false;
220 }
221 return true;
222 }
223
224 }
225