apr_hash_t *hashOfStringsFromDistOfStrings( Py::Object arg, SvnPool &pool ) { Py::Dict dict( arg ); apr_hash_t *hash = apr_hash_make( pool ); std::string type_error_message; try { Py::List all_keys( dict.keys() ); for( Py::List::size_type i=0; i<all_keys.length(); i++ ) { type_error_message = "expecting string key in dict"; Py::Bytes key( asUtf8Bytes( all_keys[i] ) ); type_error_message = "expecting string value in dict"; Py::Bytes value( asUtf8Bytes( dict[ key ] ) ); char *hash_key = apr_pstrdup( pool, key.as_std_string().c_str() ); svn_string_t *hash_value = svn_string_create( value.as_std_string().c_str(), pool ); apr_hash_set( hash, hash_key, APR_HASH_KEY_STRING, hash_value ); } } catch( Py::TypeError & ) { throw Py::TypeError( type_error_message ); } return hash; }
int main (int argc, char ** argv) { log_to_output (get_option ('v', &argc, argv)); if (argc < 2) { printf ("usage: %s contact-name [message]\n", argv [0]); printf (" or: %s -k contact-name [hops [secret]] (hops defaults to 1)\n", argv [0]); return 1; } int sock = xchat_init (argv [0]); if (sock < 0) return 1; int ack_expected = 0; long long int seq = 0; char * contact = argv [1]; /* contact we send to, peer we receive from */ char * kcontact = NULL; char * my_secret = NULL; char * peer_secret = NULL; #define MAX_SECRET 15 /* including a terminating null character */ char my_secret_buf [MAX_SECRET]; char peer_secret_buf [200]; int kmax_hops = 0; int wait_time = 5000; /* 5 seconds to wait for acks and such */ if (strcmp (contact, "-k") == 0) { /* send a key */ if ((argc != 3) && (argc != 4) && (argc != 5)) { printf ("usage: %s -k contact-name [hops [secret]] (%d)\n", argv [0], argc); return 1; } kcontact = argv [2]; int hops = 1; if (argc >= 4) { char * end; int n = strtol (argv [3], &end, 10); if (end != argv [3]) hops = n; } random_string (my_secret_buf, MAX_SECRET); if (hops <= 1) my_secret_buf [6] = '\0'; /* for direct contacts, truncate to 6 chars */ printf ("%d hops, my secret string is '%s'", hops, my_secret_buf); normalize_secret (my_secret_buf); printf (" (or %s)\n", my_secret_buf); my_secret = my_secret_buf; if (argc >= 5) { snprintf (peer_secret_buf, sizeof (peer_secret_buf), "%s", argv [4]); printf ("peer secret string is '%s'", peer_secret_buf); normalize_secret (peer_secret_buf); printf (" (or %s)\n", peer_secret_buf); peer_secret = peer_secret_buf; } kmax_hops = hops; wait_time = 10 * 60 * 1000; /* wait up to 10 minutes for a key */ char * send_secret = my_secret; if (! create_contact_send_key (sock, kcontact, send_secret, peer_secret, hops)) return 1; } else { /* send the data packet */ int i; keyset * keys; int nkeys = all_keys (contact, &keys); if ((argc > 2) && (nkeys > 0)) { int max_key = 0; for (i = 0; i < nkeys; i++) { allnet_rsa_prvkey key; int ksize = get_my_privkey (keys [i], &key); if (ksize > max_key) max_key = ksize; } static char text [ALLNET_MTU]; int size = sizeof (text) - CHAT_DESCRIPTOR_SIZE - ALLNET_SIZE (ALLNET_TRANSPORT_ACK_REQ) - max_key; /* the maximum size of a signature */ char * p = text; int printed = 0; for (i = 2; i < argc; i++) { int n = snprintf (p, size, "%s%s", argv [i], (i + 1 < argc) ? " " : ""); printed += n; p += n; size -= n; } /* printf ("sending %d chars: '%s'\n", printed, text); */ seq = send_data_message (sock, contact, text, printed); ack_expected = 1; } else if (nkeys == 0) { printf ("error: no keys for contact '%s'\n", contact); } else if (nkeys < 0) { printf ("error: contact '%s' does not exist\n", contact); } } struct timeval start, deadline; gettimeofday (&start, NULL); gettimeofday (&deadline, NULL); add_time (&deadline, wait_time); int max_wait = until_deadline (&deadline); int ack_seen = 0; while (max_wait > 0) { char * packet; int pipe, pri; int found = receive_pipe_message_any (max_wait, &packet, &pipe, &pri); if (found < 0) { printf ("xchats pipe closed, exiting\n"); exit (1); } int verified, duplicate, broadcast; char * desc; char * message; char * peer = NULL; keyset kset = -1; int mlen = handle_packet (sock, packet, found, &peer, &kset, &message, &desc, &verified, NULL, &duplicate, &broadcast, kcontact, my_secret, peer_secret, kmax_hops, NULL, NULL, 0); if (mlen > 0) { char * ver_mess = ""; if (! verified) ver_mess = " (not verified)"; char * dup_mess = ""; if (duplicate) dup_mess = "duplicate "; char * bc_mess = ""; if (broadcast) { bc_mess = "broacast "; dup_mess = ""; desc = ""; } printf ("from '%s'%s got %s%s%s\n %s\n", peer, ver_mess, dup_mess, bc_mess, desc, message); } else if (mlen == -1) { /* successful key exchange */ printf ("success! got remote key for %s\n", kcontact); gettimeofday (&deadline, NULL); add_time (&deadline, 5000); /* wait 5 more seconds */ } /* handle_packet may change what has been acked */ if ((ack_expected) && (! ack_seen) && (is_acked (contact, seq))) { struct timeval finish; gettimeofday (&finish, NULL); /* how long did the ack take? */ long long int delta = (finish.tv_sec - start.tv_sec ) * 1000000LL + (finish.tv_usec - start.tv_usec); printf ("got ack from %s in %lld.%06llds\n", contact, delta / 1000000, delta % 1000000); gettimeofday (&deadline, NULL); /* wait another second from now */ add_time (&deadline, 1000); /* for additional messages */ ack_seen = 1; } if (mlen > 0) { free (peer); free (message); if (! broadcast) free (desc); } max_wait = until_deadline (&deadline); } return 0; }
static int handle_key (int sock, struct allnet_header * hp, char * data, int dsize, char * contact, char * secret1, char * secret2, int max_hops) { #ifdef DEBUG_PRINT printf ("in handle_key (%s, %s, %s)\n", contact, secret1, secret2); #endif /* DEBUG_PRINT */ if ((contact == NULL) || (secret1 == NULL)) return 0; if (hp->hops > max_hops) return 0; keyset * keys; int nkeys = all_keys (contact, &keys); if (nkeys < 1) { printf ("error '%s'/%d: create own key before calling handle_key\n", contact, nkeys); return 0; } #ifdef DEBUG_PRINT printf ("handle_key received key\n"); #endif /* DEBUG_PRINT */ unsigned char peer_addr [ADDRESS_SIZE]; int peer_bits; int key_index = -1; int i; for (i = 0; i < nkeys; i++) { allnet_rsa_pubkey key; peer_bits = get_remote (keys [i], peer_addr); if ((get_contact_pubkey (keys [i], &key) <= 0) && ((peer_bits <= 0) || (matches (peer_addr, peer_bits, hp->source, hp->src_nbits) > 0))) { #ifdef DEBUG_PRINT printf ("handle_key matches at index %d/%d\n", i, nkeys); #endif /* DEBUG_PRINT */ key_index = i; break; } } if (key_index < 0) { if (nkeys <= 0) printf ("handle_key error: contact '%s' has %d keys\n", contact, nkeys); /* it is fairly normal to get multiple copies of the key. Ignore. else printf ("handle_key: contact '%s' has %d keys, no unmatched key found\n", contact, nkeys); */ return 0; } char * received_key = data; int ksize = dsize - SHA512_SIZE; /* check to see if it is my own key */ for (i = 0; i < nkeys; i++) { allnet_rsa_pubkey k; get_my_pubkey (keys [i], &k); char test_key [ALLNET_MTU]; int pub_ksize = allnet_pubkey_to_raw (k, test_key, sizeof (test_key)); if ((pub_ksize == ksize) && (memcmp (received_key, test_key, ksize) == 0)) { /* it is fairly normal to get my own key back. Ignore. */ printf ("handle_key: got my own key\n"); return 0; } } char * received_hmac = data + ksize; char hmac [SHA512_SIZE]; sha512hmac (received_key, ksize, secret1, strlen (secret1), hmac); int found1 = (memcmp (hmac, received_hmac, SHA512_SIZE) == 0); int found2 = 0; if ((! found1) && (secret2 != NULL)) { sha512hmac (received_key, ksize, secret2, strlen (secret2), hmac); found2 = (memcmp (hmac, received_hmac, SHA512_SIZE) == 0); } #ifdef DEBUG_PRINT printf ("hmac gives %d/%d\n", found1, found2); #endif /* DEBUG_PRINT */ if ((found1) || (found2)) { #ifdef DEBUG_PRINT printf ("received valid public key %p/%d for '%s'/%d\n", received_key, ksize, contact, key_index); print_buffer (received_key, ksize, "key", 10, 1); #endif /* DEBUG_PRINT */ if (set_contact_pubkey (keys [key_index], received_key, ksize)) { if (hp->src_nbits > 0) set_contact_remote_addr (keys [key_index], hp->src_nbits, hp->source); /* send the key to the peer -- may be redundant, but may be useful */ char * secret = secret1; if (found2) /* use peer's secret */ secret = secret2; /* else peer sent us a valid key, must know our secret1 */ printf ("sending back key with secret %s\n", secret); if (! send_key (sock, contact, keys [key_index], secret, hp->source, hp->src_nbits, max_hops)) printf ("send_key failed for key index %d/%d\n", key_index, nkeys); return -1; /* successful key exchange */ } printf ("handle_key error: set_contact_pubkey returned 0\n"); return 0; } #ifdef DEBUG_PRINT printf ("public key does not check with secrets %s %s\n", secret1, secret2); #endif /* DEBUG_PRINT */ return 0; }