?? auth.cc
字號:
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-// Copyright (c) 2001-2008 XORP, Inc.//// Permission is hereby granted, free of charge, to any person obtaining a// copy of this software and associated documentation files (the "Software")// to deal in the Software without restriction, subject to the conditions// listed in the XORP LICENSE file. These conditions include: you must// preserve this copyright notice, and you cannot mention the copyright// holders in advertising related to the Software without their permission.// The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This// notice is a summary of the XORP LICENSE file; the license in that file is// legally binding.#ident "$XORP: xorp/rip/auth.cc,v 1.38 2008/07/23 05:11:34 pavlin Exp $"#include "rip_module.h"#include "libxorp/xorp.h"#include "libxorp/xlog.h"#include "libxorp/eventloop.hh"#include <functional>#include <openssl/md5.h>#include "constants.hh"#include "auth.hh"// ----------------------------------------------------------------------------// AuthHandlerBase implementationAuthHandlerBase::~AuthHandlerBase(){}const string&AuthHandlerBase::error() const{ return _err;}inline voidAuthHandlerBase::reset_error(){ if (_err.empty() == false) _err.erase();}inline voidAuthHandlerBase::set_error(const string& err){ _err = err;}// ----------------------------------------------------------------------------// NullAuthHandler implementationconst char*NullAuthHandler::effective_name() const{ return auth_type_name();}const char*NullAuthHandler::auth_type_name(){ return "none";}voidNullAuthHandler::reset(){}uint32_tNullAuthHandler::head_entries() const{ return 0;}uint32_tNullAuthHandler::max_routing_entries() const{ return RIPv2_ROUTES_PER_PACKET;}boolNullAuthHandler::authenticate_inbound(const uint8_t* packet, size_t packet_bytes, const uint8_t*& entries_ptr, uint32_t& n_entries, const IPv4&, bool){ entries_ptr = NULL; n_entries = 0; if (packet_bytes > RIPv2_MAX_PACKET_BYTES) { set_error(c_format("packet too large (%u bytes)", XORP_UINT_CAST(packet_bytes))); return false; } else if (packet_bytes < RIPv2_MIN_PACKET_BYTES) { set_error(c_format("packet too small (%u bytes)", XORP_UINT_CAST(packet_bytes))); return false; } size_t entry_bytes = packet_bytes - RipPacketHeader::size(); if (entry_bytes % PacketRouteEntry<IPv4>::size()) { set_error(c_format("non-integral route entries (%u bytes)", XORP_UINT_CAST(entry_bytes))); return false; } n_entries = entry_bytes / PacketRouteEntry<IPv4>::size(); if (n_entries == 0) { return true; } entries_ptr = packet + RipPacketHeader::size(); const PacketRouteEntry<IPv4> entry(entries_ptr); // Reject packet if first entry is authentication data if (entry.is_auth_entry()) { set_error(c_format("unexpected authentication data (type %d)", entry.tag())); entries_ptr = NULL; n_entries = 0; return false; } reset_error(); return true;}boolNullAuthHandler::authenticate_outbound(RipPacket<IPv4>& packet, list<RipPacket<IPv4> *>& auth_packets, size_t& n_routes){ // XXX: nothing to do so just create a single copy RipPacket<IPv4>* copy_packet = new RipPacket<IPv4>(packet); auth_packets.push_back(copy_packet); reset_error(); n_routes = packet.data_bytes() - RipPacketHeader::size(); n_routes /= PacketRouteEntry<IPv4>::size(); return (true);}// ----------------------------------------------------------------------------// Plaintext handler implementationconst char*PlaintextAuthHandler::effective_name() const{ return auth_type_name();}const char*PlaintextAuthHandler::auth_type_name(){ return "simple";}voidPlaintextAuthHandler::reset(){}uint32_tPlaintextAuthHandler::head_entries() const{ return 1;}uint32_tPlaintextAuthHandler::max_routing_entries() const{ return RIPv2_ROUTES_PER_PACKET - 1;}boolPlaintextAuthHandler::authenticate_inbound(const uint8_t* packet, size_t packet_bytes, const uint8_t*& entries_ptr, uint32_t& n_entries, const IPv4&, bool){ entries_ptr = NULL; n_entries = 0; if (packet_bytes > RIPv2_MAX_PACKET_BYTES) { 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; } size_t entry_bytes = packet_bytes - RipPacketHeader::size(); if (entry_bytes % PacketRouteEntry<IPv4>::size()) { set_error(c_format("non-integral route entries (%u bytes)", XORP_UINT_CAST(entry_bytes))); return false; } const PlaintextPacketRouteEntry4 ppr(packet + RipPacketHeader::size()); if (ppr.addr_family() != PlaintextPacketRouteEntry4::ADDR_FAMILY) { set_error("not an authenticated packet"); return false; } else if (ppr.auth_type() != PlaintextPacketRouteEntry4::AUTH_TYPE) { set_error("not a plaintext authenticated packet"); return false; } string passwd = ppr.password(); if (passwd != key()) { set_error(c_format("wrong password \"%s\"", passwd.c_str())); return false; } reset_error(); n_entries = entry_bytes / PacketRouteEntry<IPv4>::size() - 1; if (n_entries) { entries_ptr = (packet + RipPacketHeader::size() + PlaintextPacketRouteEntry4::size()); } return true;}boolPlaintextAuthHandler::authenticate_outbound(RipPacket<IPv4>& packet, list<RipPacket<IPv4> *>& auth_packets, size_t& n_routes){ uint8_t* first_entry_ptr = NULL; if (head_entries() > 0) first_entry_ptr = packet.route_entry_ptr(0); static_assert(PacketRouteEntry<IPv4>::SIZE == 20); static_assert(PlaintextPacketRouteEntry4::SIZE == 20); XLOG_ASSERT(packet.data_ptr() + RipPacketHeader::size() == first_entry_ptr); PlaintextPacketRouteEntry4Writer ppr(first_entry_ptr); ppr.initialize(key()); // XXX: just create a single copy RipPacket<IPv4>* copy_packet = new RipPacket<IPv4>(packet); auth_packets.push_back(copy_packet); reset_error(); n_routes = packet.data_bytes() - RipPacketHeader::size(); n_routes /= PacketRouteEntry<IPv4>::size(); n_routes--; // XXX: exclude the first (authentication) entry return (true);}const string&PlaintextAuthHandler::key() const{ return _key;}voidPlaintextAuthHandler::set_key(const string& plaintext_key){ _key = string(plaintext_key, 0, 16);}// ----------------------------------------------------------------------------// MD5AuthHandler::MD5Key implementationMD5AuthHandler::MD5Key::MD5Key(uint8_t key_id, const string& key, const TimeVal& start_timeval, const TimeVal& end_timeval, XorpTimer start_timer, XorpTimer stop_timer) : _id(key_id), _start_timeval(start_timeval), _end_timeval(end_timeval), _is_persistent(false), _o_seqno(0), _start_timer(start_timer), _stop_timer(stop_timer){ string::size_type n = key.copy(_key_data, 16); if (n < KEY_BYTES) { memset(_key_data + n, 0, KEY_BYTES - n); }}stringMD5AuthHandler::MD5Key::key() const{ return string(_key_data, 0, 16);}boolMD5AuthHandler::MD5Key::valid_at(const TimeVal& when) const{ if (is_persistent()) return true; return ((_start_timeval <= when) && (when <= _end_timeval));}voidMD5AuthHandler::MD5Key::reset(){ // // Reset the seqno // _lr_seqno.clear(); // // Reset the flag that a packet has been received // _pkts_recv.clear();}voidMD5AuthHandler::MD5Key::reset(const IPv4& src_addr){ map<IPv4, uint32_t>::iterator seqno_iter; map<IPv4, bool>::iterator recv_iter; // // Reset the seqno // seqno_iter = _lr_seqno.find(src_addr); if (seqno_iter != _lr_seqno.end()) _lr_seqno.erase(seqno_iter); // // Reset the flag that a packet has been received // recv_iter = _pkts_recv.find(src_addr); if (recv_iter != _pkts_recv.end()) _pkts_recv.erase(recv_iter);}boolMD5AuthHandler::MD5Key::packets_received(const IPv4& src_addr) const{ map<IPv4, bool>::const_iterator iter; iter = _pkts_recv.find(src_addr); if (iter == _pkts_recv.end()) return (false); return (iter->second);}uint32_tMD5AuthHandler::MD5Key::last_seqno_recv(const IPv4& src_addr) const{ map<IPv4, uint32_t>::const_iterator iter; iter = _lr_seqno.find(src_addr); if (iter == _lr_seqno.end()) return (0); return (iter->second);}voidMD5AuthHandler::MD5Key::set_last_seqno_recv(const IPv4& src_addr, uint32_t seqno){ map<IPv4, uint32_t>::iterator seqno_iter; map<IPv4, bool>::iterator recv_iter; // // Set the seqno // seqno_iter = _lr_seqno.find(src_addr); if (seqno_iter == _lr_seqno.end()) _lr_seqno.insert(make_pair(src_addr, seqno)); else seqno_iter->second = seqno; // // Set the flag that a packet has been received // recv_iter = _pkts_recv.find(src_addr); if (recv_iter == _pkts_recv.end()) _pkts_recv.insert(make_pair(src_addr, true)); else recv_iter->second = true;}// ----------------------------------------------------------------------------// MD5AuthHandler implementationMD5AuthHandler::MD5AuthHandler(EventLoop& eventloop) : _eventloop(eventloop){}const char*MD5AuthHandler::effective_name() const{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -