Source: ../../rip/auth.hh


 
LOGO
 Annotated List  Files  Globals  Hierarchy  Index  Top
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-

// Copyright (c) 2001-2004 International Computer Science Institute
//
// 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.

// $XORP: xorp/rip/auth.hh,v 1.5 2004/06/10 22:41:43 hodson Exp $

#ifndef __RIP_AUTH_HH__
#define __RIP_AUTH_HH__

#include <list>
#include <vector>
#include "packets.hh"

/**
 * @short Base clase for RIPv2 authentication mechanisms.
 *
 * The AuthHandlerBase class defines the interfaces for RIPv2
 * authentication handlers.  Handlers are responsible for
 * authenticating inbound datagrams and adding authentication data to
 * outbound datagrams.
 *
 * Error during authentication set an error buffer that clients may
 * query using the error() method.
 */
class AuthHandlerBase
{
public:
    virtual ~AuthHandlerBase();

    /**
     * Inbound authentication method.
     *
     * @param packet pointer to first byte of RIP packet.
     * @param packet_bytes number of bytes in RIP packet.
     * @param entries_start output variable set to point to first
     *        entry in packet.  Set to 0 if there are no entries, or
     *        on authentication failure.
     * @param n_entries number of entries in the packet.
     *
     * @return true if packet passes authentication checks, false otherwise.
     */
    virtual bool authenticate(const uint8_t*			packet,
			      size_t				packet_bytes,
			      const PacketRouteEntry<IPv4>*&	entries,
			      uint32_t&				n_entries) = 0;

    /**
     * Outbound authentication method.
     *
     * @param packet pointer to first byte of RIP packet.
     * @param packet_bytes number of bytes in RIP packet.
     * @param first_entry pointer to first entry in RIP packet.
     * @param trailer_data vector of data authentication scheme use for
     *        authenication scheme data to appear at end of packet sent.
     * @return number of packet entries on success, 0 when no valid keys
     * are present.
     */
    virtual uint32_t authenticate(const uint8_t*	  packet,
				  size_t		  packet_bytes,
				  PacketRouteEntry<IPv4>* first_entry,
				  vector<uint8_t>& 	  trailer_data) = 0;

    /**
     * Get number of routing entries used by authentication scheme at the
     * head of the RIP packet.  0 for unauthenticated packets, 1 otherwise.
     */
    virtual uint32_t head_entries() const = 0;

    /**
     * Get maximum number of non-authentication scheme use routing entries
     * in a RIP packet.
     */
    virtual uint32_t max_routing_entries() const = 0;

    /**
     * Get name of authentication scheme.
     */
    virtual const char* name() const = 0;

    /**
     * Get textual description of last error.
     */
    const string& error() const;

protected:
    /**
     * Reset textual description of last error.
     */
    inline void reset_error();

    /**
     * Set textual description of latest error.
     */
    inline void set_error(const string& err);

private:
    string _err;
};


/**
 * @short RIPv2 Authentication handler when no authentication scheme is
 * employed.
 */
class NullAuthHandler : public AuthHandlerBase
{
public:
    bool authenticate(const uint8_t*			packet,
		      size_t				packet_bytes,
		      const PacketRouteEntry<IPv4>*&	entries_start,
		      uint32_t&				n_entries);

    uint32_t authenticate(const uint8_t*	  packet,
			  size_t		  packet_bytes,
			  PacketRouteEntry<IPv4>* first_entry,
			  vector<uint8_t>&	  trailer_data);

    uint32_t head_entries() const;

    uint32_t max_routing_entries() const;

    const char* name() const;

    static const char* auth_type_name();
};

/**
 * @short RIPv2 Authentication handler for plaintext scheme.
 */
class PlaintextAuthHandler : public AuthHandlerBase
{
public:
    bool authenticate(const uint8_t*			packet,
		      size_t				packet_bytes,
		      const PacketRouteEntry<IPv4>*&	entries_start,
		      uint32_t&				n_entries);

    uint32_t authenticate(const uint8_t*	  packet,
			  size_t		  packet_bytes,
			  PacketRouteEntry<IPv4>* first_entry,
			  vector<uint8_t>&	  trailer_data);

    uint32_t head_entries() const;

    uint32_t max_routing_entries() const;

    const char* name() const;

    static const char* auth_type_name();

    void set_key(const string& plaintext_key);

    const string& key() const;

protected:
    string _key;
};


/**
 * @short RIPv2 Authentication handler for MD5 scheme.
 *
 * Class to check inbound MD5 authenticated packets and add
 * authentication data to outbound RIP packets. The RIP MD5
 * authentication scheme is described in RFC 2082.
 */
class MD5AuthHandler : public AuthHandlerBase
{
public:
    /**
     * Structure to hold MD5 key information.
     */
    struct MD5Key
    {
	static const uint32_t KEY_BYTES = 16;

	/**
	 * Construct an MD5 Key.
	 */
	MD5Key(uint8_t		id,
	       const string&	key,
	       uint32_t		start_secs,
	       XorpTimer	to) ;

	/**
	 * Get the id associated with the key.
	 */
	inline uint8_t	id() const			{ return _id; }

	/**
	 * Get pointer to key data.  The data is of size KEY_BYTES.
	 */
	const char*	key_data() const		{ return _key_data; }

	/**
	 * Get the size of the key data in bytes.
	 */
	inline uint32_t	key_data_bytes() const		{ return KEY_BYTES; }

	/**
	 * Get key data as a string.
	 */
	string	 	key() const;

	/**
	 * Get the start time of the key.
	 */
	inline uint32_t	start_secs() const		{ return _start_secs; }

	/**
	 * Get the end time of the key.  If the end time is the same as the
	 * start time, the key is persistent and never expires.
	 */
	uint32_t	end_secs() const;

	/**
	 * Get indication of whether key is persistent.
	 */
	bool		persistent() const;

	/**
	 * Get whether id matches a particular value (convenient for STL
	 * algorithms).
	 */
	inline bool	id_matches(uint8_t o) const	{ return _id == o; }

	/**
	 * Get key validity status of key at a particular time.
	 * @param when_secs time in seconds since midnight 1 Jan 1970.
	 */
	bool	 	valid_at(uint32_t when_secs) const;

	/**
	 * Indicate whether valid packets have been received with this key id.
	 */
	inline bool	packets_received() const 	{ return _pkts_recv; }

	/**
	 * Get last received sequence number
	 * @return last sequence number seen.  Value may be garbage if
	 * no packets have been received (check first with
	 * @ref packets_received())
	 */
	inline uint32_t	last_seqno_recv() const		{ return _lr_sno; }

	/**
	 * Set last sequence number received.  This method implicitly
	 * set packets received to true.
	 */
	inline void set_last_seqno_recv(uint32_t sno);

	/**
	 * Get next sequence number for outbound packets.  The counter
	 * is automatically updated with each call of this method.
	 */
	inline uint32_t next_seqno_out()		{ return _o_sno++; }

    protected:
	uint8_t   _id;
	char	  _key_data[KEY_BYTES];
	uint32_t  _start_secs;
	bool	  _pkts_recv;		// true if packets received
	uint32_t  _lr_sno;		// last received seqno
	uint32_t  _o_sno;		// next outbound sequence number
	XorpTimer _to;			// expiry timeout

	friend class MD5AuthHandler;
    };

    typedef list<MD5Key> KeyChain;

    /**
     * Get iterator pointing at first key valid at a particular time.
     *
     * @param when_secs time in seconds since midnight 1 Jan 1970.
     */
    KeyChain::const_iterator key_at(uint32_t when_secs) const;

public:
    /**
     * Constructor
     *
     * @param e the EventLoop instance to used for time reference.
     * @param timing_slack_secs the amount of slack in time comparisons, eg
     * the amount of time a key is accepted before or after it's validity
     * period.
     */
    MD5AuthHandler(EventLoop& e, uint32_t timing_slack_secs = 3600);

    bool authenticate(const uint8_t*			packet,
		      size_t				packet_bytes,
		      const PacketRouteEntry<IPv4>*&	entries_start,
		      uint32_t&				n_entries
		      );

    uint32_t authenticate(const uint8_t*	  packet,
			  size_t		  packet_bytes,
			  PacketRouteEntry<IPv4>* first_entry,
			  vector<uint8_t>&	  trailer_data);

    uint32_t head_entries() const;

    uint32_t max_routing_entries() const;

    const char* name() const;

    static const char* auth_type_name();

    /**
     * Add key to MD5 key chain.  If key already exists, it is updated with
     * new settings.  If the start and end times are the same the key
     * is treated as persistant and will not expire.
     *
     * @param key_id unique id associated with key.
     * @param key phrase used for MD5 digest computation.
     * @param start_secs start time in seconds since midnight 1 Jan 1970.
     * @param end_secs start time in seconds since midnight 1 Jan 1970.
     *
     * @return true on success, false if end time is less than start time
     * or key has already expired.
     */
    bool add_key(uint8_t	id,
		 const string&	key,
		 uint32_t	start_secs,
		 uint32_t	end_secs);

    /**
     * Remove key from MD5 key chain.
     *
     * @param key_id unique id of key to be removed.
     */
    void remove_key(uint8_t id);

    /**
     * Get currently active key.
     *
     * @return key id in range 0-255 if key exists,
     * value outside valid range otherwise 256-65535.
     */
    uint16_t currently_active_key() const;

    /**
     * Get all keys managed by MD5AuthHandler.
     *
     * @return list of keys.
     */
    inline const KeyChain& key_chain() const		{ return _key_chain; }

protected:
    /**
     * Get iterator pointing at first key valid at a particular time.
     *
     * @param when_secs time in seconds since midnight 1 Jan 1970.
     */
    KeyChain::iterator key_at(uint32_t when_secs);

protected:
    EventLoop&	_e;
    KeyChain	_key_chain;
    uint32_t	_slack_secs;
};

#endif // __RIP_AUTH_HH__

Generated by: pavlin on possum.icir.org on Thu Jul 8 23:48:39 2004, using kdoc $.