X-Git-Url: http://git.pjr.cc/?p=pengine.git;a=blobdiff_plain;f=lib%2FinterComms.php;h=980a5573788be883b43b3da2549aad1996f4daa0;hp=52d874da815986645de76cc3ee29f664a3594d3b;hb=HEAD;hpb=c0b76ea046b221cafdc183a2a79d31ff9400ed19 diff --git a/lib/interComms.php b/lib/interComms.php index 52d874d..980a557 100644 --- a/lib/interComms.php +++ b/lib/interComms.php @@ -2,40 +2,270 @@ define("NETCOM_PORT", 14001); define("NETCOM_PORT_SSL", 14002); + +// comms on this thing are very serial, the server are only capable of processing +// one thing at a time... for now + +// the encryption we use here yes, it will be pub/priv but not ssl per se. +// how encryption works: +// initiate connection: +// server -> PEN:b64enc(pubkey):INE +// client -> PEN:ACK:INE +// client -> PEN:encrypt(pubkey, session key):INE +// server -> PEN:ACK:INE +// client -> PEN:encrypt(data, session key):INE <-- data transmission starts here +// server -> PEN:ACK:INE + class netCom { - function __construct($am_i_a_server = false, $server_addr = "127.0.0.1") + function __construct($am_i_a_server = false, $server_addr = "127.0.0.1", $secure = false) { + global $storeLocation; + // i have to set it to something, right? - $semKey = ftok(__FILE__, "pengine"); - $encrypt = false; + $this->semKey = ftok(__FILE__, "p"); + $this->encrypt = $secure; + + $this->amserver = $am_i_a_server; + $this->server = $server_addr; - $amserver = $am_i_a_server; - $server = $server_addr; + $this->secure_server = $secure; + // this bit needs to be a bit more modular + if($this->amserver && $this->secure_server) if(is_file("$storeLocation/mykey.priv")) { + echo "loading key\n"; + $kh = fopen("$storeLocation/mykey.priv", "r"); + $kdp = fread($kh, filesize("$storeLocation/mykey.priv")); + + $key = openssl_pkey_get_private($kdp); + $output = ""; + $km = openssl_pkey_export($key, $output); + echo "key is $output\n"; + $this->key_priv = $output; + + $ar_pubkey = openssl_pkey_get_details($key); + $this->key_pub = $ar_pubkey["key"]; + + + } else { + echo "generateing key\n"; + $key = openssl_pkey_new(); + echo "key generated $key\n"; + $output = ""; + $km = openssl_pkey_export($key, $output); + echo "key is $output\n"; + $ar_pubkey = openssl_pkey_get_details($key); + $pubkey = $ar_pubkey["key"]; + echo "array is $pubkey\n"; + // now lets write some shit + $priv_f = fopen("$storeLocation/mykey.priv", "w"); + fwrite($priv_f, $output); + $this->key_priv = $output; + fclose($priv_f); + + $pub_f = fopen("$storeLocation/mykey.pub", "w"); + fwrite($pub_f, $pubkey); + $this->key_pub = $pubkey; + fclose($pub_f); + + + } } // initiates a bind if its a server, a connect if its a client - function go() + function go($callback = "") { if($this->amserver) { - + echo "i am a server, bind!\n"; + // here we fork our server + $pid = pcntl_fork(); + if($pid == -1) { + return false; + // fork failure + } else if ($pid) { + return true; + // parent + } else { + // child + if($this->secure_server) { + $this->startSecureServerListener($callback); + } else { + $this->startServerListener($callback); + } + } + } else { + echo "I am a client, connect!\n"; + if($this->secure_server) { + $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); + $res = socket_connect($this->socket, $this->server, NETCOM_PORT_SSL); + } else { + $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); + $res = socket_connect($this->socket, $this->server, NETCOM_PORT); + + } } } - function serverLoop() + function startSecureServerListener($callback) { + $this->listen_socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); + socket_bind($this->listen_socket, $this->server, NETCOM_PORT_SSL); + socket_listen($this->listen_socket); + while(true) { + $newsock = socket_accept($this->listen_socket); + echo "Have a new conneciton\n"; + // i now have a connection + $pid = pcntl_fork(); + if($pid == -1) return false; + else if (!$pid) { + secureConnection($callback, $newsock); + } + } } - function sendMessage() + function secureConnection($callback, $socket) { + // when the secure conneciton starts, we send out pub key + sendMessageInternal($this->key_pub, $socket); + + // then we get a session key + $sesskey_enc = receiveMessageInternal($socket); + // which we decrypt using our priv key and store. + $this->session_key = openssl_private_decypt(); + + // now we go into a message loop. } - function receiveMessage() + function startServerListener($callback) { + $this->listen_socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); + socket_bind($this->listen_socket, $this->server, NETCOM_PORT); + socket_listen($this->listen_socket); + while(true) { + $newsock = socket_accept($this->listen_socket); + echo "Have a new conneciton\n"; + // i now have a connection + $pid = pcntl_fork(); + if($pid == -1) return false; + else if (!$pid) { + $this->insecureConnection($callback, $newsock); + } + } + } + + function insecureConnection($callback, $socket) + { + $continue = true; + while($continue) { + // wait for a message + $msg_s = $this->receiveMessageInternal($socket); + if(!$msg_s) { + echo "Connection handler dieing 1\n"; + return false; + } + $msg = unserialize($msg_s); + $retmsg = $callback($msg); + $retval = $this->sendMessageInternal(serialize($retmsg), $socket); + if(!$retval) { + echo "Connection handler dieing 2\n"; + return false; + } + } + } + + function sendMessage($data) + { + $continue = true; + + $returned = false; + if($this->secure_server) { + $returned = $this->sendMessageSecure($data); + } else { + $returned = $this->sendMessageInsecure($data); + } + + return $returned; + } + + function sendMessageInsecure($data) + { + $this->sendMessageInternal(serialize($data), $this->socket); + $returned = $this->receiveMessageInternal($this->socket); + + return unserialize($returned); + } + + function sendMessageInternal($message_data, $comsock) + { + echo "begin send message\n"; + $datacomp = base64_encode($message_data); + $tosend = "PEN:$datacomp:INE"; + + $retval = socket_send($comsock, $tosend, strlen($tosend), 0); + if(!$retval) { + echo "in smi, retval false\n"; + return false; + } + echo "end send message $retval\n"; + // get up to one meg of data - this is bad... i can feel this function + // hurting alot + // TODO FIX THIS - its garbage code... im not really sure how to handle this really + // we need to read back as AS:data:EOD - i think it now does.. i hope, tho we need + // timeouts now. + // we wait for an ack + $size = socket_recv($comsock, $recv, 1024, 0); + if($recv != "PEN:ACK:INE") { + echo "invalid response?\n$recv\n"; + } else { + echo "smi got ack\n"; + } + + return true; + } + + function receiveMessageInternal($comsock) + { + echo "begin recieve message\n"; + $recvd = ""; + $continue = true; + while($continue) { + $size = socket_recv($comsock, $recvd_a, 1024, 0); + + if($size === false) { + echo "recevie in rmi was false\n"; + return false; + } + $recvd .= $recvd_a; + echo "got $recvd_a so far for $size\n"; + if($size == 0) return false; + if(preg_match("/.*\:INE$/", $recvd)) { + // we have a full string... break out + $continue = false; + break; + } + } + + + echo "rec msg next\n"; + // first check we got something that makes sense + if(preg_match("/^PEN:.*:INE$/", $recvd) < 1) { + socket_close($comsock); + echo "Returned data is not in right format\n"; + // we have a problem jim + return false; + } + $msg = "PEN:ACK:INE"; + socket_send($comsock, $msg, strlen($msg), 0); + + echo "got a data packet\n"; + $xps = explode(":", $recvd); + + $component = base64_decode($xps[1]); + + return $component; } @@ -44,8 +274,12 @@ class netCom { private $encrypt; private $semKey; private $amserver; + private $secure_server; private $socket; - private $socket_ssl; + private $listen_socket; + private $key_priv; + private $key_pub; + private $session_key; }