예제 #1
0
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);
}
예제 #2
0
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);
}
예제 #3
0
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);
}
예제 #4
0
파일: ei_connect.c 프로젝트: 616050468/otp
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 */
예제 #5
0
파일: gsasl.c 프로젝트: baohaojun/dico
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;
}
예제 #6
0
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);
}