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;
}
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;
}