int Proxy_final_verify(Proxy *conn) { assert_mem(conn); assert_mem(conn->state); log(INFO, "Verifying final established crypto between peers."); check_err(conn->host.name, INVALID_HUB, "No name given for Hub after connect."); check_err(conn->client.name, INVALID_CLIENT, "No client name configured, how'd you do that?"); check_err(biseq(conn->host.name, conn->state->them.name), PEER_VERIFY, "Expected Hub name and given Hub name do not match."); check_err(biseq(conn->client.name, conn->state->me.name), INVALID_CLIENT, "Final client name and given client name do not match."); check_err(biseq(conn->host.key, conn->host_given_key), PEER_VERIFY, "Expected and given Hub keys do not match."); bstring host_fp = CryptState_fingerprint_key(conn->state, CRYPT_THEIR_KEY, PK_PUBLIC); bstring client_pub_fp = CryptState_fingerprint_key(conn->state, CRYPT_MY_KEY, PK_PUBLIC); bstring client_pub = CryptState_export_key(conn->state, CRYPT_MY_KEY, PK_PUBLIC); bstring client_prv_fp = CryptState_fingerprint_key(conn->state, CRYPT_MY_KEY, PK_PRIVATE); bstring client_prv = CryptState_export_key(conn->state, CRYPT_MY_KEY, PK_PRIVATE); Node *host_info = Node_cons("[s[bsww", conn->state->them.name, conn->host_given_key, host_fp, "public", "their"); check_err(host_info, STACKISH, "Failed to construct valid host name:key response."); Node *my_info = Node_cons("[s[bsw[bsww", conn->state->me.name, client_prv, client_prv_fp, "private", client_pub, client_pub_fp, "public", "my"); check_err(my_info, STACKISH, "Failed to construct valid client name:key response."); check_err(Proxy_listener_send(conn, host_info, my_info), LISTENER_IO, "Failed to write initial connect response to listener."); log(INFO, "Peering cryptography validated. Hub should be OK."); return 1; on_fail(Proxy_dump_invalid_state(conn); return 0); }
int Proxy_listener_send(Proxy *conn, Node *header, Node *body) { assert_mem(header); assert_mem(conn); int rc = writenodes(conn->client.write_fd, header, body); check_err(rc > 0, LISTENER_IO, "Failed to write data to client listener."); Node_destroy(body); Node_destroy(header); ensure(return rc > 0); }
int Proxy_connect(Proxy *conn) { Node *rhdr = NULL, *rmsg = NULL; Node *imsg = NULL; bstring header = NULL; int rc = 0; assert_mem(conn); CryptState_init(); // create the peer crypto we need conn->state = CryptState_create(conn->client.name, conn->client.key); check_err(conn->state, CRYPTO, "Failed to initialize cryptography subsystem."); conn->state->data = conn; log(INFO, "Connecting to %s:%s as %s expecting server named %s", bdata(conn->host.host), bdata(conn->host.port), bdata(conn->client.name), bdata(conn->host.name)); // connect to the hub conn->host.fd = tcp_client((char *)bdata(conn->host.host), (char *)bdata(conn->host.port)); check_err(conn->host.fd >= 0, NET, "Failed to connect to Hub."); rmsg = readnodes(conn->host.fd, &rhdr); check_err(!rmsg && rhdr, PEER_ESTABLISH, "Incorrectly formatted initial message from Hub."); // generate first response imsg = CryptState_initiator_start(conn->state, rhdr, &header, Proxy_confirm_key); Node_destroy(rhdr); rhdr = NULL; check_err(imsg, PEER_ESTABLISH, "Failed to construct response to Hub's first message."); rc = write_header_node(conn->host.fd, header, imsg); Node_destroy(imsg); imsg = NULL; bdestroy(header); header = NULL; check_err(rc > 0, PEER_ESTABLISH, "Failed sending response to Hub's first message."); rmsg = readnodes(conn->host.fd, &rhdr); check_err(rmsg && rhdr, PEER_ESTABLISH, "Invalid response from hub."); header = Node_bstr(rhdr, 1); Node_destroy(rhdr); rhdr = NULL; rc = CryptState_initiator_process_response(conn->state, header, rmsg); check_err(rc, PEER_ESTABLISH, "Failed to process receiver 2nd message."); Node_destroy(rmsg); bdestroy(header); header = NULL; rmsg = NULL; imsg = CryptState_initiator_send_final(conn->state, &header); check_err(imsg, PEER_ESTABLISH, "Failed to generate final message."); rc = write_header_node(conn->host.fd, header, imsg); check_err(rc > 0, PEER_ESTABLISH, "Failed to write final message to hub."); check_err(Proxy_final_verify(conn), PEER_VERIFY, "Final verify of Hub info failed."); // remember, rc>0 is how we make sure that everything went ok during processing ensure(if(imsg) Node_destroy(imsg); if(rmsg) Node_destroy(rmsg); if(rhdr) Node_destroy(rhdr); if(header) bdestroy(header); return rc > 0); }
int Proxy_event_loop(Proxy *conn) { // find out the maxfd possible int maxfd = conn->host.fd < conn->client.read_fd ? conn->client.read_fd : conn->host.fd; maxfd = maxfd < conn->client.write_fd ? conn->client.write_fd : maxfd; int rc = 0; fd_set readmask, readset; fd_set writemask, writeset; Node *header[2] = {NULL, NULL}; Node *body[2] = {NULL, NULL}; assert_mem(conn); FD_ZERO(&readset); FD_ZERO(&writeset); FD_SET(conn->host.fd, &readset); FD_SET(conn->client.read_fd, &readset); while(1) { readmask = readset; writemask = writeset; rc = select(maxfd+1, &readmask, &writemask, NULL, NULL); check_err(rc != 0, IO, "Failed to get an event from select call."); check_err(rc > 0, IO, "Error running select event loop."); PROXY_HANDLE_EVENT(HUB, conn->host.fd, Proxy_hub_recv, conn->client.write_fd, Proxy_listener_send); PROXY_HANDLE_EVENT(LISTENER, conn->client.read_fd, Proxy_listener_recv, conn->host.fd, Proxy_hub_send); } return 1; on_fail(return 0); }
int Proxy_confirm_key(CryptState *state) { assert_mem(state); assert_mem(state->data); Proxy *conn = (Proxy *)state->data; conn->host_given_key = CryptState_export_key(state, CRYPT_THEIR_KEY, PK_PUBLIC); if(conn->host.key && !biseq(conn->host_given_key, conn->host.key)) { fail("Expected Hub public key does not match given Hub public key from the host."); } log(INFO, "Hub identity confirmed and keys exchanged. Keep them safe."); return 1; on_fail(Proxy_dump_invalid_state(conn); return 0); }
Node *Proxy_hub_recv(Proxy *conn, Node **header) { Node *msg = NULL, *packet = NULL; bstring hdata = NULL; assert_mem(header); assert_mem(conn); packet = readnodes(conn->host.fd, header); check_err(packet && *header, HUB_IO, "Failed to read hub message."); hdata = Node_bstr(*header, 1); check_err(hdata, STACKISH, "Failed to convert stackish header from hub into a string for decrypt."); msg = CryptState_decrypt_node(conn->state, &conn->state->me.skey, hdata, packet); check_err(msg, CRYPTO, "Failed to decrypt payload from hub."); ensure(Node_destroy(packet); bdestroy(hdata); return msg); }
Route *Route_alloc(Route *parent, const char *name) { Route *r = h_calloc(1, sizeof(Route)); assert_mem(r); r->name = bfromcstr(name); assert_mem(r->name); r->members = Heap_create(NULL); r->children = Heap_create(Route_children_compare); // add it to the children mapping if(parent) { hattach(r, parent); Heap_add(parent->children, r); } return r; }
int Proxy_hub_send(Proxy *conn, Node *header, Node *body) { bstring hdata = NULL; Node *msg = NULL; int rc = 0; assert_mem(header); assert_mem(body); assert_mem(conn); hdata = Node_bstr(header, 1); msg = CryptState_encrypt_node(conn->state, &conn->state->them.skey, hdata, body); check_then(msg, "failed to encrypt payload", rc = -1); rc = write_header_node(conn->host.fd, hdata, msg); check_err(rc > 0, HUB_IO, "Failed to write encrypted message."); ensure(if(msg) Node_destroy(msg); if(hdata) bdestroy(hdata); Node_destroy(header); Node_destroy(body); return rc > 0); }
int main() { byte *raw = (byte *) "\x9f\x06\x05\xa0\x00\x00\x03\x33" \ "\x9f\x22\x01\x01" \ "\xdf\x02\x10" \ "\x80\xc8\x90\x20\x2e\xb6\x66\x51" \ "\xc4\xfc\x2c\xbe\x6d\xa9\xc5\xbe"; byte *tags[] = {(byte *)"\x9f\x06", (byte *)"\x9f\x22", (byte *)"\xdf\x02", NULL}; byte *test_value; byte buf[32]; int test_len; test_begin; tlv_build(raw, tags); test_len = tlv_getValue((byte *)"\xdf\x02", &test_value); assert_eq(test_len, 16); assert_mem(test_value, "\x80\xc8\x90\x20\x2e\xb6\x66\x51" \ "\xc4\xfc\x2c\xbe\x6d\xa9\xc5\xbe", test_len); test_len = tlv_getValue((byte *)"\x9f\x06", &test_value); assert_eq(test_len, 0x05); assert_mem(test_value, "\xa0\x00\x00\x03\x33", test_len); test_len = tlv_dump(buf, tags); assert_mem(buf, raw, test_len); tlv_setValue((byte *)"\xdf\x02", 5, (byte *)"Hello"); test_len = tlv_getValue((byte *)"\xdf\x02", &test_value); assert_eq(test_len, 5); assert_mem(test_value, "Hello", 5); tlv_free(); test_end; return 0; }
bstring Node_bstr(Node *d, int follow_sibs) { int rc = 0; bstring temp = bfromcstr(""); assert_mem(temp); assert_not(d, NULL); Node_catbstr(temp, d, ' ', follow_sibs); rc = bconchar(temp, '\n'); assert(rc == BSTR_OK && "failed to append separator char"); return temp; }
inline Node *Node_create(Node *parent, enum NodeType type) { Node *node = node_test_calloc(); assert_mem(node); node->type = type; // now just add the new node on to the current's children if(parent) { node->parent = parent; LIST_ADD(Node, parent->child, node, sibling); } return node; }
inline ConnectionState *Hub_new_or_reuse_conn(Hub *hub) { ConnectionState *state = NULL; if((state = hub->closed) != NULL) { // there's some dead ones we can reuse SGLIB_LIST_DELETE(ConnectionState, hub->closed, state, next); memset(state, 0, sizeof(ConnectionState)); } else { // nothing we can reuse, make a new one state = calloc(1,sizeof(ConnectionState)); } assert_mem(state); return state; }
void Proxy_destroy(Proxy *conn) { assert_mem(conn); close(conn->client.write_fd); close(conn->client.read_fd); bdestroy(conn->client.name); bdestroy(conn->client.key); close(conn->host.fd); bdestroy(conn->host.name); bdestroy(conn->host.port); bdestroy(conn->host.key); bdestroy(conn->host.host); // sometimes the state isn't correct, so let the system clean for now // if(conn->state) CryptState_destroy(conn->state); }
void get_memory_for_matrix( Int4 dim_, T ** &matr_) { matr_=NULL; bool ee_error_flag=false; error ee_error("",0); try { try { Int4 i; matr_=new T *[dim_]; assert_mem(matr_); for(i=0;i<dim_;i++) { matr_[i]=NULL; }; for(i=0;i<dim_;i++) { matr_[i]=new T [dim_]; assert_mem(matr_[i]); }; d_memory_size_in_MB+=(double)sizeof(T)*(double)dim_*(double)dim_/mb_bytes; } catch (error er) { ee_error_flag=true; ee_error=er; }; } catch (...) { ee_error_flag=true; ee_error=error("Internal error in the program\n",4); }; //memory release if(ee_error_flag) { if(matr_) { Int4 i; for(i=0;i<dim_;i++) { if(matr_[i]) { delete[]matr_[i];matr_[i]=NULL; }; }; delete[]matr_;matr_=NULL; }; throw error(ee_error.st,ee_error.error_code); }; };