aboutsummaryrefslogtreecommitdiffstats
path: root/mayor-orig/www/include/share/ssl/ssl.php
blob: 0b6e2e04a515287c5d16ed3c969127b326c01b8e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
<?php
/*

    Küldés:

    Fogadás:
	skin=rpc
	    rights.php
		require_once ssl.php
		$_POST[senderNodeId] beolvasás
		$RPC construct...
		setRemoteNodeId
		processRequest (sessionKey, request)
	    *-pre.php
		getIncomingRequest ($request['func'])
		prepareReply
		    _encodeRequest
		setMyResponse
	    skin-rpc/base.phtml
		global $RPC
		echo $RPC->getResponse()

    Küldés:
	    __construct
		getSSLKeyPair
		_genSessionKey
	    setRemoteNodeId
		_setRemotePublicKey
		    getSslPublicKeyByNodeId
	    setRemoteHost (HOST, publicKey)
		_setRemotePublicKey
	    setRequestTarget (PSF)
	    sendRequest
		_prepareRequest
		_encodeRequest($ADAT)
		    AES::encrypt !! json, base64 - nincs AES :(
		    _sessionKeyEncode
		_curlGet --> response
		_decodeRequest !! jelenleg csak json...
		_sessionKeyDecode
		json_decode - AES::decrypt
*/

    function getSslKeyPair() {
	$q = "SELECT * FROM mayorSsl";
	$r = db_query($q, array('fv'=>'getSslKeyPair','modul'=>'login','result'=>'record'));
	if ($r=='') {
		$SSLKeyPair = generateSSLKeyPair();
		$secret = sha1(mt_rand(100000000000000,999999999999999));
		$q = "INSERT INTO mayorSsl (privateKey,publicKey,secret) VALUES ('%s','%s','%s')";
		$values = array($SSLKeyPair['privateKey'],$SSLKeyPair['publicKey'],$secret);
		$r = db_query($q, array('fv'=>'getSslKeyPair','modul'=>'login', 'values'=>$values));
		return $SSLKeyPair;
	} else {
	    return $r;
	}
    }

    function generateSSLKeyPair() {
        $SSL_KEY_PAIR=openssl_pkey_new();
        // Get private key
        openssl_pkey_export($SSL_KEY_PAIR, $privatekey);
        // Get public key
        $publickey=openssl_pkey_get_details($SSL_KEY_PAIR);                                                                                                                                                
        $publickey=$publickey["key"];                                                                                                                                                                                               
	return array('fv'=>'geneateSslKeyPair','privateKey'=>$privatekey,'publicKey'=>$publickey);                        
    }
    function setNodeId($nodeId, $publicKey) {
	$q = "UPDATE mayorSsl SET nodeId=%u where publicKey='%s'";
	$v = array($nodeId, $publicKey);
	return db_query($q, array('debug'=>false,'fv'=>'setNodeId','modul'=>'login', 'values'=>$v));
    }

    function getSslPublicKey() {
	$SSLKeyPair = getSslKeyPair();
	return $SSLKeyPair['publicKey'];
    }

    function getSslPublicKeyByNodeId($nodeId) {
	if (is_numeric($nodeId)) {
	    $q = "SELECT publicKey FROM mayorKeychain WHERE valid=1 AND nodeId='%u'";
	    $values = array($nodeId);
	    $result = db_query($q, array('debug'=>false,'fv'=>'getSslPublicKeyByNodeId','modul'=>'login', 'values'=>$values,'result'=>'value'));
	    if ($result=='') return false;
	    else return $result;
	} else {
	    return false;
	}
    }

    function getPublicDataFromLocalKeychain($nodeId) {
	if (is_numeric($nodeId)) {
	    // lekérdezés a helyi adatbázisból
	    $q = "SELECT * FROM mayorKeychain WHERE valid=1 AND nodeId='%u'";
	    $values = array($nodeId);
	    $result = db_query($q, array('debug'=>false,'fv'=>'getPublicDataFromLocalKeychain','modul'=>'login', 'values'=>$values,'result'=>'record'));
	    if ($result=='') return false;
	    else return $result;
	} elseif (is_null($nodeId)) {
	    // Az összes eltárolt node adatának lekérdezése
	    $q = "SELECT * FROM mayorKeychain WHERE valid=1 ORDER BY nodeTipus DESC, nev";
	    $result = db_query($q, array('debug'=>false,'fv'=>'getPublicDataFromLocalKeychain','modul'=>'login','result'=>'indexed'));
	    if ($result=='') return false;
	    else return $result;	    
	}
    }

    function addPublicDataToLocalKeychain($DATA) {
	// egy új rekord felvétele...
	$fields = array_keys($DATA);
	$values = array_values($DATA);
	$q = "INSERT INTO mayorKeychain (".implode(',', array_fill(0, count($fields), "%s")).") VALUES (".implode(',', array_fill(0, count($values), "'%s'")).")";
	$v = array_merge($fields, $values);
	$r = db_query($q, array('debug'=>false,'func'=>'addPublicDataToLocalKeychain','modul'=>'login','values'=>$v,'result'=>'insert'));
	return $r;
    }
    function removeNodeFromLocalKeychain($nodeId) {
	$q = "DELETE FROM mayorKeychain WHERE nodeId=%u";
	$v = array($nodeId);
	$r = db_query($q, array('debug'=>false,'func'=>'removeNodeFromLocalKeychain','modul'=>'login','values'=>$v));
	return $r;	
    }
    function sendPublicRequest($data) {
	if (defined('_DEVEL') && _DEVEL===true) $host = 'localhost';
	else $host = 'www.mayor.hu';
	$url = "https://$host/index.php?page=portal&sub=regisztracio&f=regisztracio&skin=ajax";
	$salt_name='MS_'.sha1('portal_regisztracio_regisztracio');
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // a választ feldolgozzuk
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYSTATUS, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // a helyi gépen nekem ez kellett :(
            curl_setopt($ch, CURLOPT_HEADER, 0);
//          curl_setopt($ch, CURLOPT_TIMEOUT,60);
            curl_setopt($ch, CURLOPT_USERAGENT, "MaYoR-registration (php; cURL)");
            curl_setopt($ch, CURLOPT_VERBOSE, true);
	    // Cookie
	    curl_setopt($ch, CURLOPT_COOKIE, $salt_name.'=portal_regisztracio_regisztracio');
            // POST
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
         
            $response = curl_exec($ch);
            $INFO = curl_getinfo($ch); // ha kell
            if ($INFO['http_code'] == 200) { // minden ok
                //dump($INFO['url']);
                //dump("response:",$response);
            } else {
                echo '<a href="'.$url.'">URL</a>';
                dump($INFO['http_code'],$response,$INFO);
                throw new Exception($INFO['http_code']);
            }
            curl_close($ch);

        return $response;
    }
    
//function base64url_encode($data) { 
//  return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); 
//} 
//function base64url_decode($data) { 
//  return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT)); 
//}
function random_str($length, $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
{
    $str = '';
    $max = mb_strlen($keyspace, '8bit') - 1;
    for ($i = 0; $i < $length; ++$i) {
        $str .= $keyspace[random_int(0, $max)];
    }
    return $str;
}
    /* symmetric cryptographic module */
    class AES {

	public function __construct() { }
	public function encrypt($data, $key) {
	    $data = urlencode($data);

//	    $return = $data;
//	    $return = $key . $data;
//	    $return = openssl_encrypt($data, 'aes-256-cbc', $key, OPENSSL_RAW_DATA);
//	    $return = db_query("SELECT aes_encrypt('%s','%s')",array('fv'=>'class AES','result'=>'value','modul'=>'login','values'=>array($data,$key)));

	    if (function_exists('mcrypt_encrypt')) {
		$return = mcrypt_encrypt(MCRYPT_RIJNDAEL_128,$key,$data,MCRYPT_MODE_CBC,"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
	    } else {
		$_SESSION['alert'][] = 'info:mcrypt függvény nem található (tipp! telepítsd a php5-mcrypt csomagot a szerverre)';
	    }
	    return base64_encode($return);
	}
	public function decrypt($data,$key) {
	    $data = base64_decode($data);

//	    $return = $data;
//	    $return = substr($data,strlen($key));
//	    $return = openssl_decrypt($data, 'aes-256-cbc', $key, OPENSSL_RAW_DATA);
//	    $return = db_query("SELECT aes_decrypt('%s','%s')",array('fv'=>'class AES','result'=>'value','modul'=>'login','values'=>array($data,$key)));
	    if (function_exists('mcrypt_decrypt')) {
		$return = mcrypt_decrypt(MCRYPT_RIJNDAEL_128,$key,$data,MCRYPT_MODE_CBC,"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
	    } else {
		$_SESSION['alert'][] = 'info:mcrypt függvény nem található (tipp! telepítsd a php5-mcrypt csomagot a szerverre)';
	    }
	    return trim(urldecode($return));
	}
    }

    class Interconnect {

	/*  A: küldő, B: fogadó használja  */

	private $sessionKey;	// egy kommunikációhoz használt session kulcs
	private $KP;		// a saját kulcspárom
	private $nodeId;
	private $privateKey;
	private $publicKey;
	private $remotePublicKey;
	private $remoteNodeId;
	private $remoteHost;
	private $psf;
	private $myRequest;		// a küldendő kérés (object)
	private $myResponse;		// a küldendő válasz (object)
	private $incomingRequest;	// a beérkező kérés (object)
	private $incomingResponse;	// a beérkező válasz (object)
	private $status;		// a művelet eredményességéek visszajelzése, hibaok kódja...
	private $controllerNodeId = '09862967'; // Ez van jelenleg az adatbázisban...

	/* Konstruktor */
	public function __construct() {
	    $this->sessionKey  = $this->_genSessionKey();
	    $this->KP = getSSLKeyPair();
	    $this->nodeId = $this->KP['nodeId'];
	    $this->privateKey = $this->KP['privateKey'];
	    $this->publicKey = $this->KP['publicKey'];
	    $this->status = 'ok:created';
	    $this->psf = 'page=rpc&f=rpc';
	}
	/* Privát metódusok */
//        private function _yconv($get) {
//            $get = str_replace(' ','+',$get);   // hm. erre miért van szükség??? autokonverzió?
//            $get = str_replace('\/','/',$get);  // hm. erre miért van szükség??? autokonverzió?
//            $get = str_replace('\\','',$get);  // hm. erre miért van szükség??? autokonverzió?\"'
//            return $get;
//        }
	private function _curlGet($data) {
	    $host = $this->remoteHost;
	    $url = $this->remoteHost."/index.php?skin=rpc&".$this->psf;
	    //dump('url',$url);
	    $ch = curl_init();
	    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // a választ feldolgozzuk
	    curl_setopt($ch, CURLOPT_URL, $url);
	    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
	    curl_setopt($ch, CURLOPT_SSL_VERIFYSTATUS, false);
	    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
	    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // a helyi gépen nekem ez kellett :(
	    curl_setopt($ch, CURLOPT_HEADER, 0); 
//	    curl_setopt($ch, CURLOPT_TIMEOUT,60);
	    curl_setopt($ch, CURLOPT_USERAGENT, "MaYoR-interconnect (php; cURL)");
	    curl_setopt($ch, CURLOPT_VERBOSE, true);
	    // POST
	    $data['senderNodeId'] = $this->nodeId;
	    curl_setopt($ch, CURLOPT_POST, true);
	    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));

	    $response = curl_exec($ch);
	    $INFO = curl_getinfo($ch); // ha kell
	    if ($INFO['http_code'] == 200) { // minden ok
		//dump($INFO['url']);
		//dump($response);
	    } else {
		echo '<a href="'.$url.'">URL</a>';
		dump($response,$INFO);
		throw new Exception($INFO['http_code']);
	    }
	    curl_close($ch);
	    return $response;
	}
	private function _genSessionKey() {
	    return base64_encode(pack('N6', mt_rand(), mt_rand(), mt_rand(),mt_rand(), mt_rand(), mt_rand()));
	    //return random_str( 32 );
	}
	private function _sessionKeyEncode() {
	    $crypttext = '';
	    $res = openssl_public_encrypt($this->sessionKey, $crypttext, $this->remotePublicKey); // majd a távoli publikus kulccal
    	    return base64_encode($crypttext);
	}
	private function _sessionKeyDecode($in) {
	    $decodedtext = '';
    	    $res = openssl_private_decrypt(base64_decode($in), $decodedtext, $this->privateKey); // a saját privát kulccsal
    	    return $decodedtext;
	}
	private function _genHash($in) {
	    // hash generálás
	    return hash('sha256', $in, false);
	}
	private function _hashEncode($in) {
	    // a mi privát kulcsunkkal...
    	    $res = openssl_private_encrypt($in, $encodedHash, $this->privateKey); // a saját privát kulccsal
    	    return base64_encode($encodedHash);
	}
	private function _hashDecode($in) {
	    // a remotePublic-kal
	    $res = openssl_public_decrypt(base64_decode($in), $decodedHash, $this->remotePublicKey); // majd a távoli publikus kulccal
    	    return $decodedHash;
	}
	private function _verifyHash($PACKED) {
	    return ($this->_genHash($PACKED['details']))===($this->_hashDecode($PACKED['hashEncoded']));
	}
	private function _packData($DATA) { // --> array(details|sessionKeyEncoded)
	    $ADAT['details'] = AES::encrypt(json_encode($DATA),$this->sessionKey); // implicit base64_encode
	    $ADAT['hashEncoded'] = $this->_hashEncode($this->_genHash($ADAT['details'])); 
	    $ADAT['sessionKeyEncoded'] = $this->_sessionKeyEncode(); // implicit base64_encode
	    $ADAT['status'] = $this->status;
	    return $ADAT;
	}
	private function _unpackData($PACKED) { // packed[details] --> object !! feltesszük, hogy már be van állítva a sessionKey, ellenőrizve van a hash!
	    return json_decode(AES::decrypt($PACKED['details'],$this->sessionKey), true);
	}
	private function _encodeRequest($IN = array()) { // HTTP GET paraméter
	    return urlencode(json_encode($IN)); 
	}
	private function _decodeRequest($IN) { // HTTP GET paraméter
	    return json_decode($IN, true);
	}
	private function _encodeResponse($IN=array()) { // HTTP - tartalom
	    return json_encode($IN);
	}
	private function _decodeResponse($IN=array()) { // HTTP - tartalom
	    return json_decode($IN, true);
	}
	/* Publikus metódusok */
	public function setRequestTarget($target) {
	    if ($target == 'controller') $this->psf='page=rpc&sub=controller&f=rpc';
	    else if ($target == 'naplo') $this->psf='page=rpc&sub=naplo&f=rpc';
	    else $this->psf='page=rpc&f=rpc'; // alap funkciók
	}
	public function getRegistrationDataByNodeId($nodeId) { // feltesszük, hogy valid
	    $origRemoteNodeId = $this->remoteNodeId;
	    $this->setRemoteHostByNodeId($this->controllerNodeId);
	    $ret = $this->sendRequest(array('func'=>'getPublicDataByNodeId', 'nodeId'=>$nodeId));
	    $this->setRemoteHostByNodeId($origRemoteNodeId);

	    return $ret;
	}
	public function getPublicDataByNodeId($nodeId) {
	    if (defined('_DEVEL') && _DEVEL===true) {
		// A helyi gép adatait adjuk meg
		$ret = array('nodeId'=>$this->nodeId, 'url'=>'https://localhost','publicKey'=>$this->publicKey);
	    } else {
		if ($nodeId == '') $nodeId = $this->controllerNodeId;
		// Adott nodeId adatainak lekérdezése a helyi adatbázisból
		$ret = getPublicDataFromLocalKeychain($nodeId);
		if ($ret === false) {
		    $RPC = new Interconnect();
		    $RPC->setRequestTarget('controller');
		    $RPC->setRemoteHostByNodeId($this->controllerNodeId);
		    $ret2 = $RPC->sendRequest(array('func'=>'getPublicDataByNodeId', 'nodeId'=>$nodeId));
		    $ret = $ret2['nodeData'];
		    foreach (array(
			'regId','dij','utemezes','egyebTamogatas','szamlazasiCim','szamlaHelyseg','szamlaIrsz','szamlaKozteruletNev',
			'szamlaKozteruletJelleg','szamlaHazszam'
		    ) as $field) {
			unset($ret[$field]);
		    }
		    if (is_array($ret)) addPublicDataToLocalKeychain($ret);
/*
		} elseif (false) {
		    // Adott nodeId adatainak lekérdezése a www.mayor.hu-tól (controller) Interconnect-tel
		    $origRemoteNodeId = $this->remoteNodeId;
		    $origPsf = $this->psf;
		    $this->setRequestTarget('controller');
		    $this->setRemoteHostByNodeId($this->controllerNodeId);
		    $ret2 = $this->sendRequest(array('func'=>'getPublicDataByNodeId', 'nodeId'=>$nodeId));
		    $ret = $ret2['nodeData'];
		    foreach (array(
			'regId','dij','utemezes','egyebTamogatas','szamlazasiCim','szamlaHelyseg','szamlaIrsz','szamlaKozteruletNev',
			'szamlaKozteruletJelleg','szamlaHazszam'
		    ) as $field) {
			unset($ret[$field]);
		    }
		    if (is_array($ret)) addPublicDataToLocalKeychain($ret);
		    if ($origRemoteNodeId!='') $this->setRemoteHostByNodeId($origRemoteNodeId);		    
		    $this->psf = $origPsf;
*/
		}
	    }
	    return $ret;
    	}
	public function setRemoteHostByNodeId($nodeId) {
	    $rData = $this->getPublicDataByNodeId($nodeId);
	    if (is_array($rData)) {
		$this->remoteHost = $rData['url'];
		$this->remoteNodeId = $rData['nodeId'];
		$this->remotePublicKey = $rData['publicKey'];
		$this->status = 'ok:remoteHost';
	    } else {
		$this->remoteHost = ''; // controller
		$this->remoteNodeId = $this->controllerNodeId;
		$this->remotePublicKey = $rData['publicKey'];
		$this->status = 'ok:remoteHostController';
	    }
	}
	/* A oldal */
	public function sendRequest($ADAT = array()) {
	    $PACKED = $this->_packData($ADAT);
	    $this->myRequest = $PACKED;
	    // $this->myRequest = $this->_encodeRequest($PACKED);

	    $response = $this->_curlGet($this->myRequest);

	    $decodedResponse = $this->_decodeResponse($response);
	    if ($this->sessionKey === $this->_sessionKeyDecode($decodedResponse['sessionKeyEncoded'])) {
		if ($this->_verifyHash($decodedResponse)) {
		    $this->incomingResponse = $this->_unpackData($decodedResponse);
		    $this->status = 'ok:success response';
		} else {
		    $this->incomingResponse = false;
		    $this->status = 'error:wrong response hash';
		}
	    } else {
		$this->status = 'error:wrong response sessionKey ('.($this->sessionKey).' != '.($this->_sessionKeyDecode($decodedResponse['sessionKeyEncoded'])).') response: '.$response;
		$this->incomingResponse = false;
	    }
	    return $this->incomingResponse;
	}
	/* B oldal! */
	public function processRequest() { 	// rights.php
	    $PACKED = $_POST;
	    $this->sessionKey = $this->_sessionKeyDecode($PACKED['sessionKeyEncoded']);
	    if ($this->_verifyHash($PACKED)) {
		$this->incomingRequest = $this->_unpackData($PACKED);
openlog("MaYoR Interconnect", LOG_PID | LOG_PERROR, LOG_LOCAL0);
syslog(LOG_WARNING, "Data unpacked: ".(json_encode($this->incomingRequest))." {$_SERVER['REMOTE_ADDR']} ({$_SERVER['HTTP_USER_AGENT']})");
closelog();
		$this->status = 'ok:success request';
	    } else {
		$this->incomingRequest = false;
		$this->status = 'error:wrong request hash';		
	    }
	    return $this->incomingRequest;
	}
	public function setResponse($DATA) { // ez kell a pre-be
	    $this->myResponse = $this->_encodeResponse($this->_packData($DATA));
	}
	public function sendResponse() { // skin=rpc - csak ki kell írnunk az elküldendő adatsort - ezt a skin csinálja
	    echo $this->myResponse;
	}
	public function getIncomingRequest() { return $this->incomingRequest; } // a pre-ben

	public function getPublicKey() { return $this->publicKey; }
	public function getSessionKey() { return $this->sessionKey; }
	public function getStatus() { return $this->status; }
	public function getRemoteNodeId() { return $this->remoteNodeId; }
	public function getControllerNodeId() { return $this->controllerNodeId; }
	public function getNodeId() { return $this->nodeId; }
    }


?>