static void recv_ok(CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen) { USE_PRIV; if (processor->state != INIT) { close_processor(processor); return; } /* check version */ if (clen != 0) { int v = get_version(content); if ((priv->used_version = get_used_version(v)) == -1) { ccnet_processor_send_error_update(processor, SC_VERSION_MISMATCH, SS_VERSION_MISMATCH); close_processor(processor); return; } } else { ccnet_processor_send_error_update(processor, SC_VERSION_MISMATCH, SS_VERSION_MISMATCH); close_processor(processor); return; } if (processor->peer->net_state == PEER_DOWN) ccnet_peer_set_net_state (processor->peer, PEER_INDIRECT); if (processor->peer->pubkey) send_challenge(processor); else get_pubkey(processor); }
static void recv_pubkey(CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen) { g_assert (processor->state == WAIT_PUBKEY); if (clen == 0 || content[clen-1] != '\0') { ccnet_debug ("[Conn] Bad public key format\n"); close_processor (processor); return; } ccnet_peer_set_pubkey (processor->peer, content); if (processor->peer->pubkey == NULL) { ccnet_debug ("[Conn] Bad public key format\n"); close_processor (processor); return; } send_challenge (processor); }
bool metakey_h(connection_t *c, const char *request) { if(!myself->connection->rsa) return false; char hexkey[MAX_STRING_SIZE]; int cipher, digest, maclength, compression; const size_t len = rsa_size(myself->connection->rsa); char enckey[len]; char key[len]; if(sscanf(request, "%*d %d %d %d %d " MAX_STRING, &cipher, &digest, &maclength, &compression, hexkey) != 5) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "METAKEY", c->name, c->hostname); return false; } /* Convert the challenge from hexadecimal back to binary */ int inlen = hex2bin(hexkey, enckey, sizeof enckey); /* Check if the length of the meta key is all right */ if(inlen != len) { logger(DEBUG_ALWAYS, LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong keylength"); return false; } /* Decrypt the meta key */ if(!rsa_private_decrypt(myself->connection->rsa, enckey, len, key)) { logger(DEBUG_ALWAYS, LOG_ERR, "Error during decryption of meta key for %s (%s)", c->name, c->hostname); return false; } if(debug_level >= DEBUG_SCARY_THINGS) { bin2hex(key, hexkey, len); logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Received random meta key (unencrypted): %s", hexkey); } /* Check and lookup cipher and digest algorithms */ if(cipher) { if(!(c->incipher = cipher_open_by_nid(cipher)) || !cipher_set_key_from_rsa(c->incipher, key, len, false)) { logger(DEBUG_ALWAYS, LOG_ERR, "Error during initialisation of cipher from %s (%s)", c->name, c->hostname); return false; } } else { c->incipher = NULL; } if(digest) { if(!(c->indigest = digest_open_by_nid(digest, -1))) { logger(DEBUG_ALWAYS, LOG_ERR, "Error during initialisation of digest from %s (%s)", c->name, c->hostname); return false; } } else { c->indigest = NULL; } c->status.decryptin = true; c->allow_request = CHALLENGE; return send_challenge(c); }
int ei_accept_tmo(ei_cnode* ec, int lfd, ErlConnect *conp, unsigned ms) { int fd; struct sockaddr_in cli_addr; int cli_addr_len=sizeof(struct sockaddr_in); unsigned her_version, her_flags; ErlConnect her_name; erl_errno = EIO; /* Default error code */ EI_TRACE_CONN0("ei_accept","<- ACCEPT waiting for connection"); if ((fd = ei_accept_t(lfd, (struct sockaddr*) &cli_addr, &cli_addr_len, ms )) < 0) { EI_TRACE_ERR0("ei_accept","<- ACCEPT socket accept failed"); erl_errno = (fd == -2) ? ETIMEDOUT : EIO; goto error; } EI_TRACE_CONN0("ei_accept","<- ACCEPT connected to remote"); if (recv_name(fd, &her_version, &her_flags, &her_name, ms)) { EI_TRACE_ERR0("ei_accept","<- ACCEPT initial ident failed"); goto error; } if (her_version <= 4) { EI_TRACE_ERR0("ei_accept","<- ACCEPT remote version not compatible"); goto error; } else { unsigned our_challenge; unsigned her_challenge; unsigned char our_digest[16]; if (send_status(fd,"ok", ms)) goto error; our_challenge = gen_challenge(); if (send_challenge(fd, ec->thisnodename, our_challenge, her_version, ms)) goto error; if (recv_challenge_reply(fd, our_challenge, ec->ei_connect_cookie, &her_challenge, ms)) goto error; gen_digest(her_challenge, ec->ei_connect_cookie, our_digest); if (send_challenge_ack(fd, our_digest, ms)) goto error; put_ei_socket_info(fd, her_version, null_cookie, ec); } if (conp) *conp = her_name; EI_TRACE_CONN1("ei_accept","<- ACCEPT (ok) remote = %s",her_name.nodename); erl_errno = 0; /* No error */ return fd; error: EI_TRACE_ERR0("ei_accept","<- ACCEPT failed"); closesocket(fd); return ERL_ERROR; } /* ei_accept */
static int sasl_auth(dico_stream_t str, char *mechanism, char *initresp, Gsasl_session **psess) { int rc; Gsasl_session *sess_ctx; char *input; char *output; char *inbuf; size_t insize; struct sasl_data sdata = { NULL, 0 }; if (disabled_mechanism_p(mechanism)) return RC_NOMECH; rc = gsasl_server_start (ctx, mechanism, &sess_ctx); if (rc != GSASL_OK) { dico_log(L_ERR, 0, _("SASL gsasl_server_start: %s"), gsasl_strerror(rc)); return rc == GSASL_UNKNOWN_MECHANISM ? RC_NOMECH : RC_FAIL; } gsasl_callback_hook_set(ctx, &sdata); output = NULL; if (initresp) { inbuf = xstrdup(initresp); insize = strlen(initresp) + 1; } else { inbuf = NULL; insize = 0; } input = inbuf; while ((rc = gsasl_step64(sess_ctx, input, &output)) == GSASL_NEEDS_MORE) { send_challenge(str, output); free(output); output = NULL; if (get_sasl_response(str, &input, &inbuf, &insize)) return RC_FAIL; } if (rc != GSASL_OK) { dico_log(L_ERR, 0, _("GSASL error: %s"), gsasl_strerror(rc)); free(output); free(inbuf); gsasl_finish(sess_ctx); return RC_FAIL; } /* Some SASL mechanisms output data when GSASL_OK is returned */ if (output[0]) send_challenge(str, output); free(output); free(inbuf); if (sdata.username == NULL) { dico_log(L_ERR, 0, _("GSASL %s: cannot get username"), mechanism); gsasl_finish(sess_ctx); return RC_FAIL; } user_name = xstrdup(sdata.username); if (sdata.anon) { if (sasl_anon_groups) { user_groups = xdico_list_create(); dico_list_iterate (sasl_anon_groups, _append_item, user_groups); } } else dico_udb_get_groups(user_db, sdata.username, &user_groups); check_db_visibility(); *psess = sess_ctx; return RC_SUCCESS; }
bool metakey_h(connection_t *c) { char buffer[MAX_STRING_SIZE]; int cipher, digest, maclength, compression; int len; if(sscanf(c->buffer, "%*d %d %d %d %d " MAX_STRING, &cipher, &digest, &maclength, &compression, buffer) != 5) { logger(LOG_ERR, "Got bad %s from %s (%s)", "METAKEY", c->name, c->hostname); return false; } len = RSA_size(myself->connection->rsa_key); /* Check if the length of the meta key is all right */ if(strlen(buffer) != (size_t)len * 2) { logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong keylength"); return false; } /* Allocate buffers for the meta key */ c->inkey = xrealloc(c->inkey, len); if(!c->inctx) { c->inctx = EVP_CIPHER_CTX_new(); if(!c->inctx) { abort(); } } /* Convert the challenge from hexadecimal back to binary */ if(!hex2bin(buffer, buffer, len)) { logger(LOG_ERR, "Got bad %s from %s(%s): %s", "METAKEY", c->name, c->hostname, "invalid key"); return false; } /* Decrypt the meta key */ if(RSA_private_decrypt(len, (unsigned char *)buffer, (unsigned char *)c->inkey, myself->connection->rsa_key, RSA_NO_PADDING) != len) { /* See challenge() */ logger(LOG_ERR, "Error during decryption of meta key for %s (%s): %s", c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); return false; } ifdebug(SCARY_THINGS) { bin2hex(c->inkey, buffer, len); buffer[len * 2] = '\0'; logger(LOG_DEBUG, "Received random meta key (unencrypted): %s", buffer); } /* All incoming requests will now be encrypted. */ /* Check and lookup cipher and digest algorithms */ if(cipher) { c->incipher = EVP_get_cipherbynid(cipher); if(!c->incipher) { logger(LOG_ERR, "%s (%s) uses unknown cipher!", c->name, c->hostname); return false; } if(!EVP_DecryptInit(c->inctx, c->incipher, (unsigned char *)c->inkey + len - EVP_CIPHER_key_length(c->incipher), (unsigned char *)c->inkey + len - EVP_CIPHER_key_length(c->incipher) - EVP_CIPHER_iv_length(c->incipher))) { logger(LOG_ERR, "Error during initialisation of cipher from %s (%s): %s", c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); return false; } c->inbudget = byte_budget(c->incipher); c->status.decryptin = true; } else { logger(LOG_ERR, "%s (%s) uses null cipher!", c->name, c->hostname); return false; } c->inmaclength = maclength; if(digest) { c->indigest = EVP_get_digestbynid(digest); if(!c->indigest) { logger(LOG_ERR, "Node %s (%s) uses unknown digest!", c->name, c->hostname); return false; } if(c->inmaclength > EVP_MD_size(c->indigest) || c->inmaclength < 0) { logger(LOG_ERR, "%s (%s) uses bogus MAC length!", c->name, c->hostname); return false; } } else { logger(LOG_ERR, "%s (%s) uses null digest!", c->name, c->hostname); return false; } c->incompression = compression; c->allow_request = CHALLENGE; return send_challenge(c); }