⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 auth.cc

📁 RIP 协议实现
💻 CC
📖 第 1 页 / 共 2 页
字号:
    //    // XXX: if no valid keys, then don't use any authentication    //    if (_valid_key_chain.empty()) {	return (_null_handler.effective_name());    }    return auth_type_name();}const char*MD5AuthHandler::auth_type_name(){    return "md5";}voidMD5AuthHandler::reset(){    //    // XXX: if no valid keys, then don't use any authentication    //    if (_valid_key_chain.empty()) {	_null_handler.reset();	return;    }    reset_keys();}uint32_tMD5AuthHandler::head_entries() const{    //    // XXX: if no valid keys, then don't use any authentication    //    if (_valid_key_chain.empty()) {	return (_null_handler.head_entries());    }    return 1;}uint32_tMD5AuthHandler::max_routing_entries() const{    //    // XXX: if no valid keys, then don't use any authentication    //    if (_valid_key_chain.empty()) {	return (_null_handler.max_routing_entries());    }    return RIPv2_ROUTES_PER_PACKET - 1;}boolMD5AuthHandler::authenticate_inbound(const uint8_t*		packet,				     size_t			packet_bytes,				     const uint8_t*&		entries_ptr,				     uint32_t&			n_entries,				     const IPv4&		src_addr,				     bool			new_peer){    static_assert(MD5PacketTrailer::SIZE == 20);    //    // XXX: if no valid keys, then don't use any authentication    //    if (_valid_key_chain.empty()) {	if (_null_handler.authenticate_inbound(packet, packet_bytes,					       entries_ptr, n_entries,					       src_addr, new_peer)	    != true) {	    set_error(_null_handler.error());	    return (false);	}	reset_error();	return (true);    }    entries_ptr = NULL;    n_entries = 0;    if (packet_bytes > RIPv2_MAX_PACKET_BYTES + MD5PacketTrailer::size()) {	set_error(c_format("packet too large (%u bytes)",			   XORP_UINT_CAST(packet_bytes)));	return false;    }    if (packet_bytes < RIPv2_MIN_AUTH_PACKET_BYTES) {	set_error(c_format("packet too small (%u bytes)",			   XORP_UINT_CAST(packet_bytes)));	return false;    }    const MD5PacketRouteEntry4 mpr(packet + RipPacketHeader::size());    if (mpr.addr_family() != MD5PacketRouteEntry4::ADDR_FAMILY) {	set_error("not an authenticated packet");	return false;    }    if (mpr.auth_type() != MD5PacketRouteEntry4::AUTH_TYPE) {	set_error("not an MD5 authenticated packet");	return false;    }    if (mpr.auth_bytes() != MD5PacketTrailer::size()) {	set_error(c_format("wrong number of auth bytes (%d != %u)",			   mpr.auth_bytes(),			   XORP_UINT_CAST(MD5PacketTrailer::size())));	return false;    }    if (uint32_t(mpr.auth_off() + mpr.auth_bytes()) != packet_bytes) {	set_error(c_format("Size of packet does not correspond with "			   "authentication data offset and size "			   "(%d + %d != %u).", mpr.auth_off(),			   mpr.auth_bytes(),			   XORP_UINT_CAST(packet_bytes)));	return false;    }    KeyChain::iterator k = find_if(_valid_key_chain.begin(),				   _valid_key_chain.end(),				   bind2nd(mem_fun_ref(&MD5Key::id_matches),					   mpr.key_id()));    if (k == _valid_key_chain.end()) {	set_error(c_format("packet with key ID %d for which no key is "			   "configured", mpr.key_id()));	return false;    }    MD5Key* key = &(*k);    if (new_peer)	key->reset(src_addr);    uint32_t last_seqno_recv = key->last_seqno_recv(src_addr);    if (key->packets_received(src_addr) && !(new_peer && mpr.seqno() == 0) &&	(mpr.seqno() - last_seqno_recv >= 0x7fffffff)) {	set_error(c_format("bad sequence number 0x%08x < 0x%08x",			   XORP_UINT_CAST(mpr.seqno()),			   XORP_UINT_CAST(last_seqno_recv)));	return false;    }    const MD5PacketTrailer mpt(packet + mpr.auth_off());    if (mpt.valid() == false) {	set_error("invalid authentication trailer");	return false;    }    MD5_CTX ctx;    uint8_t digest[16];    MD5_Init(&ctx);    MD5_Update(&ctx, packet, mpr.auth_off() + mpt.auth_data_offset());    MD5_Update(&ctx, key->key_data(), key->key_data_bytes());    MD5_Final(digest, &ctx);    if (memcmp(digest, mpt.auth_data(), mpt.auth_data_bytes()) != 0) {	set_error(c_format("authentication digest doesn't match local key "			   "(key ID = %d)", key->id()));// #define	DUMP_BAD_MD5#ifdef	DUMP_BAD_MD5	const char badmd5[] = "/tmp/rip_badmd5";	// If the file already exists don't dump anything. The file	// should contain and only one packet.	if (-1 == access(badmd5, R_OK)) {	    XLOG_INFO("Dumping bad MD5 to %s", badmd5);	    FILE *fp = fopen(badmd5, "w");	    fwrite(packet, packet_bytes, 1 , fp);	    fclose(fp);	}#endif	return false;    }    // Update sequence number only after packet has passed digest check    key->set_last_seqno_recv(src_addr, mpr.seqno());    reset_error();    n_entries = (mpr.auth_off() - RipPacketHeader::size()) /	PacketRouteEntry<IPv4>::size() - 1;    if (n_entries > 0) {	entries_ptr = (packet + RipPacketHeader::size()		       + MD5PacketRouteEntry4::size());    }    return true;}boolMD5AuthHandler::authenticate_outbound(RipPacket<IPv4>&	packet,				      list<RipPacket<IPv4> *>& auth_packets,				      size_t&		n_routes){    RipPacket<IPv4> first_packet(packet);    vector<uint8_t> first_trailer;    KeyChain::iterator iter;    static_assert(MD5PacketTrailer::SIZE == 20);    //    // XXX: if no valid keys, then don't use any authentication    //    if (_valid_key_chain.empty()) {	if (_null_handler.authenticate_outbound(packet, auth_packets,						n_routes)	    != true) {	    set_error(_null_handler.error());	    return (false);	}	reset_error();	return (true);    }    //    // Create an authenticated copy of the packet for each valid key    //    for (iter = _valid_key_chain.begin();	 iter != _valid_key_chain.end();	 ++iter) {	MD5Key& key = *iter;	RipPacket<IPv4>* copy_packet = new RipPacket<IPv4>(packet);	auth_packets.push_back(copy_packet);	uint8_t* first_entry_ptr = NULL;	if (head_entries() > 0)	    first_entry_ptr = copy_packet->route_entry_ptr(0);	MD5PacketRouteEntry4Writer mpr(first_entry_ptr);	mpr.initialize(copy_packet->data_bytes(), key.id(),		       MD5PacketTrailer::size(),		       key.next_seqno_out());	vector<uint8_t> trailer;	trailer.resize(MD5PacketTrailer::size());	MD5PacketTrailerWriter mpt(&trailer[0]);	mpt.initialize();	MD5_CTX ctx;	MD5_Init(&ctx);	MD5_Update(&ctx, copy_packet->data_ptr(), mpr.auth_off());	MD5_Update(&ctx, &trailer[0], mpt.auth_data_offset());	MD5_Update(&ctx, key.key_data(), key.key_data_bytes());	MD5_Final(mpt.auth_data(), &ctx);	//	// XXX: create a copy of the first packet without the trailer	// and of the trailer itself.	//	if (iter == _valid_key_chain.begin()) {	    first_packet = *copy_packet;	    first_trailer = trailer;	}	copy_packet->append_data(trailer);    }    packet = first_packet;    n_routes = packet.data_bytes() / MD5PacketRouteEntry4::size() - 1;    packet.append_data(first_trailer);    reset_error();    return (true);}boolMD5AuthHandler::add_key(uint8_t		key_id,			const string&	key,			const TimeVal&	start_timeval,			const TimeVal&	end_timeval,			string&		error_msg){    TimeVal now;    XorpTimer start_timer, end_timer;    string dummy_error_msg;    _eventloop.current_time(now);    if (start_timeval > end_timeval) {	error_msg = c_format("Start time is later than the end time");	return false;    }    if (end_timeval < now) {	error_msg = c_format("End time is in the past");	return false;    }    if (start_timeval > now) {	start_timer = _eventloop.new_oneoff_at(	    start_timeval,	    callback(this, &MD5AuthHandler::key_start_cb, key_id));    }    if (end_timeval != TimeVal::MAXIMUM()) {	end_timer = _eventloop.new_oneoff_at(	    end_timeval,	    callback(this, &MD5AuthHandler::key_stop_cb, key_id));    }    //    // XXX: If we are using the last authentication key that has expired,    // move it to the list of invalid keys.    //    if (_valid_key_chain.size() == 1) {	MD5Key& key = _valid_key_chain.front();	if (key.is_persistent()) {	    key.set_persistent(false);	    _invalid_key_chain.push_back(key);	    _valid_key_chain.pop_front();	}    }    // XXX: for simplicity just try to remove the key even if it doesn't exist    remove_key(key_id, dummy_error_msg);    // Add the new key to the appropriate chain    MD5Key new_key = MD5Key(key_id, key, start_timeval, end_timeval,			    start_timer, end_timer);    if (start_timer.scheduled())	_invalid_key_chain.push_back(new_key);    else	_valid_key_chain.push_back(new_key);    return true;}boolMD5AuthHandler::remove_key(uint8_t key_id, string& error_msg){    KeyChain::iterator i;    // Check among all valid keys    i = find_if(_valid_key_chain.begin(), _valid_key_chain.end(),		bind2nd(mem_fun_ref(&MD5Key::id_matches), key_id));    if (i != _valid_key_chain.end()) {	_valid_key_chain.erase(i);	return true;    }    // Check among all invalid keys    i = find_if(_invalid_key_chain.begin(), _invalid_key_chain.end(),		bind2nd(mem_fun_ref(&MD5Key::id_matches), key_id));    if (i != _invalid_key_chain.end()) {	_invalid_key_chain.erase(i);	return true;    }    error_msg = c_format("No such key");    return false;}voidMD5AuthHandler::key_start_cb(uint8_t key_id){    KeyChain::iterator i;    // Find the key among all invalid keys and move it to the valid keys    i = find_if(_invalid_key_chain.begin(), _invalid_key_chain.end(),		bind2nd(mem_fun_ref(&MD5Key::id_matches), key_id));    if (i != _invalid_key_chain.end()) {	MD5Key& key = *i;	_valid_key_chain.push_back(key);	_invalid_key_chain.erase(i);    }}voidMD5AuthHandler::key_stop_cb(uint8_t key_id){    KeyChain::iterator i;    // Find the key among all valid keys and move it to the invalid keys    i = find_if(_valid_key_chain.begin(), _valid_key_chain.end(),		bind2nd(mem_fun_ref(&MD5Key::id_matches), key_id));    if (i != _valid_key_chain.end()) {	MD5Key& key = *i;	//	// XXX: If the last key expires then keep using it as per	// RFC 2082 Section 4.3 until the lifetime is extended, the key	// is deleted by network management, or a new key is configured.	//	if (_valid_key_chain.size() == 1) {	    XLOG_WARNING("Last authentication key (key ID = %u) has expired. "			 "Will keep using it until its lifetime is extended, "			 "the key is deleted, or a new key is configured.",			 key_id);	    key.set_persistent(true);	    return;	}	_invalid_key_chain.push_back(key);	_valid_key_chain.erase(i);    }}voidMD5AuthHandler::reset_keys(){    KeyChain::iterator iter;    for (iter = _valid_key_chain.begin();	 iter != _valid_key_chain.end();	 ++iter) {	iter->reset();    }}boolMD5AuthHandler::empty() const{    return (_valid_key_chain.empty() && _invalid_key_chain.empty());}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -