+ char buffer[MAX_STRING_SIZE];
+ int len;
+cp
+ if(sscanf(cl->buffer, "%*d "MAX_STRING, buffer) != 1)
+ {
+ syslog(LOG_ERR, _("Got bad METAKEY from %s (%s)"), cl->name, cl->hostname);
+ return -1;
+ }
+
+ len = RSA_size(myself->rsa_key);
+
+ /* Check if the length of the meta key is all right */
+
+ if(strlen(buffer) != len*2)
+ {
+ syslog(LOG_ERR, _("Intruder: wrong meta key length from %s (%s)"), cl->name, cl->hostname);
+ return -1;
+ }
+
+ /* Allocate buffers for the meta key */
+
+ if(!cl->cipher_inkey)
+ cl->cipher_inkey = xmalloc(len);
+
+ if(!cl->cipher_inctx)
+ cl->cipher_inctx = xmalloc(sizeof(*cl->cipher_inctx));
+
+ /* Convert the challenge from hexadecimal back to binary */
+
+ hex2bin(buffer,buffer,len);
+
+ /* Decrypt the meta key */
+
+ if(RSA_private_decrypt(len, buffer, cl->cipher_inkey, myself->rsa_key, RSA_NO_PADDING) != len) /* See challenge() */
+ {
+ syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), cl->name, cl->hostname);
+ return -1;
+ }
+
+ if(debug_lvl >= DEBUG_SCARY_THINGS)
+ {
+ bin2hex(cl->cipher_inkey, buffer, len);
+ buffer[len*2] = '\0';
+ syslog(LOG_DEBUG, _("Received random meta key (unencrypted): %s"), buffer);
+ }
+
+ EVP_DecryptInit(cl->cipher_inctx, EVP_bf_cfb(), cl->cipher_inkey, cl->cipher_inkey + EVP_bf_cfb()->key_len);
+
+cp
+ if(cl->status.outgoing)
+ return send_ack(cl);
+ else
+ return send_metakey(cl);
+}
+
+int send_ack(connection_t *cl)
+{
+ int x;
+cp
+ if(cl->status.outgoing)
+ cl->allow_request = ACK;
+
+ x = send_request(cl, "%d", ACK);
+ cl->status.encryptout = 1;
+cp
+ return x;
+}
+
+int ack_h(connection_t *cl)
+{
+ config_t const *cfg;
+ connection_t *old, *p;
+ subnet_t *subnet;
+ avl_node_t *node, *node2;