1 /**
2   * ruleset.h
3   * part of ezbounce
4   */
5 
6 #ifndef __RULESET_H
7 #define __RULESET_H
8 
9 #include <vector>
10 #include "util/strings.h"
11 #include "util/counted_object.h"
12 #include "debug.h"
13 
14 /*
15  *  holds information stored in
16  *  allow|deny {
17  *     from ...
18  *     to ...
19  *  }
20  *  blocks in the configuration file
21  */
22 
23 class ruleset : public util::counted_object<ruleset> {
24 public:
25 	enum host_type {
26 	     FROM,
27 	     TO
28 	};
29 
30 	static const int  UNLIMITED;
31 
ruleset()32 	ruleset() : num_registered_to(0), num_registered_from(0), obsolete(false) { }
33 	virtual ~ruleset();
34 
35 	/* check if this user is permitted to connect to the server*/
36 	virtual int is_allowed(const char * host, const char * ip,
37 					unsigned short port,
38 					char *, size_t) const = 0;
39 	/* check if this user may connect to "to" */
40 	virtual int is_allowed_to(const char *to, const char * to_ip,
41 					unsigned short,
42 					char *, size_t) const = 0;
43 	/* checks if host & port are in its list of addresses */
44 	virtual bool does_match(const char *, const char *,
45 				unsigned short, host_type t) const = 0;
46 
47 	/* add a host name to the list of hosts that can connect */
48 	virtual int add_host_from(const char *address, const char *ports,
49 				const char *reason, int max);
50 
51 	/* add a host name to the list of places users can connect to */
52 	virtual int add_host_to(const char *address, const char *ports,
53 				const char *reason, int max);
54 
55 	virtual int register_connection(host_type, const char * host, const char * ip,
56 					unsigned short);
57 
58 	virtual int unregister_connection(host_type, const char * host, const char * ip,
59 					unsigned short);
60 
61 	virtual bool is_legal() const = 0;
62 
63 
64 	bool operator == (const ruleset &) const;
dead()65 	bool dead() const { return (obsolete && !num_registered_to && !num_registered_from); }
is_obsolete()66 	bool is_obsolete() const { return obsolete; }
67 
68 	static std::vector<ruleset *> * sync_lists(std::vector<ruleset *> *, std::vector<ruleset *> *);
69 
70 protected:
71 
72 	struct rsh_comp_helper
73 	{
74 		const char * host;
75 		const char * ip;
76 		unsigned short port;
rsh_comp_helperrsh_comp_helper77 		rsh_comp_helper(const char *h, const char *i, unsigned short p)
78 			: host(h), ip(i), port(p) { }
79 	};
80 
81 	struct rs_host
82 	{
83 		char * pattern;
84 		char * ports;
85 		char * reason;
86 		host_type type;
87 		int  max, num;
88 		~rs_host();
89 		rs_host(host_type, const char *, const char *, const char *, int);
90 		rs_host(const rs_host &);
91 
92 		/**
93 		  * Comparison function with helper struct: used for finding rulesets
94 		  * matching a given address/port combination.
95                   */
96 		bool operator == (const rsh_comp_helper &rh) const {
97 			return (!smart_match(rh.host, rh.ip, pattern) && port_in_set(ports, rh.port));
98 		}
99 
100 		/**
101 		  * Standard comparison method.
102 		  * NOTE: does not compare 'num' fields.
103 		  */
104 		bool operator == (const rs_host &that) const {
105 			using util::strings::safe_strcasecmp;
106 			return (type == that.type &&
107 					max == that.max &&
108 					safe_strcasecmp(pattern, that.pattern) == 0 &&
109 					safe_strcasecmp(reason, that.reason) == 0 &&
110 					safe_strcasecmp(ports, that.ports) == 0);
111 		}
112 	};
113 
114 	friend class rs_host;
115 	std::vector<rs_host> from_hosts;
116 	std::vector<rs_host> to_hosts;
117 private:
118 	/* these keep track of register_connection() and unregister_connection calls */
119 	unsigned int num_registered_to;
120 	unsigned int num_registered_from;
121 	bool 		obsolete;
122 
123 	static int smart_match(const char *, const char *, const char *);
124 	static bool port_in_set(const char *, unsigned short);
125 	static bool is_ip_pattern(const	char *);
126 
127 private:
128 	ruleset(const ruleset& );
129 	ruleset& operator= (const ruleset& );
130 };
131 
132 class allowed_ruleset : public ruleset {
133 public:
134 	int is_allowed(const char *, const char *, unsigned short, char *, size_t) const ;
135 	int is_allowed_to(const char *, const char *, unsigned short, char *, size_t) const ;
136 	int register_connection(host_type, const char *, const char *, unsigned short);
137 	int unregister_connection(host_type, const char * , const char *, unsigned short);
138 	bool does_match(const char *, const char *, unsigned short port, host_type t) const;
139 	bool is_legal() const;
140 };
141 
142 class denied_ruleset : public ruleset {
143 public:
144 	int is_allowed(const char *, const char *, unsigned short, char *, size_t) const;
145 	int is_allowed_to(const char *, const char *, unsigned short, char *, size_t) const ;
146 	bool does_match(const char *, const char *, unsigned short port, host_type t) const;
147 	bool is_legal() const;
148 };
149 
150 #endif
151