Vidalia  0.3.1
Policy.cpp
Go to the documentation of this file.
1 /*
2 ** This file is part of Vidalia, and is subject to the license terms in the
3 ** LICENSE file, found in the top level directory of this distribution. If you
4 ** did not receive the LICENSE file with this file, you may obtain it from the
5 ** Vidalia source package distributed by the Vidalia Project at
6 ** http://www.torproject.org/projects/vidalia.html. No part of Vidalia,
7 ** including this file, may be copied, modified, propagated, or distributed
8 ** except according to the terms described in the LICENSE file.
9 */
10 
11 /*
12 ** \file Policy.cpp
13 ** \brief Exit policy parsing
14 */
15 
16 #include "Policy.h"
17 
18 #include <QStringList>
19 
20 
21 /** Default constructor. Creates an AcceptAll policy. */
23 {
24  _action = Accept;
25  _address = QHostAddress::Any;
26  _fromPort = _toPort = 0;
27  _mask = 0;
28 }
29 
30 /** Constructor. Creates a new Policy object from the given string. */
31 Policy::Policy(QString policy)
32 {
33  /* Set the defaults */
34  _action = Accept;
35  _address = QHostAddress::Any;
36  _fromPort = _toPort = 0;
37  _mask = 0;
38 
39  /* Parse the given string to override the defaults. */
40  fromString(policy);
41 }
42 
43 /** Constructor. Creates a new Policy object from the string parts. */
44 Policy::Policy(QString action, QString address, QString ports)
45 {
46  /* Set the defaults */
47  _action = Accept;
48  _address = QHostAddress::Any;
49  _fromPort = _toPort = 0;
50  _mask = 0;
51 
52  fromString(action + " " + address + ":" + ports);
53 }
54 
55 /** Constructor. Creates a new Policy object depending on the specified
56  * special policy type. */
58 {
59  _action = (policy == AcceptAll ? Accept : Reject);
60  _address = QHostAddress::Any;
61  _fromPort = _toPort = 0;
62  _mask = 0;
63 }
64 
65 /** Constructor. Creates a new policy object based on the given rules. */
66 Policy::Policy(Action action, QHostAddress addr, uchar mask,
67  quint16 fromPort, quint16 toPort)
68 {
69  _action = action;
70  _address = addr;
71  _mask = mask;
72  _fromPort = fromPort;
73  _toPort = (toPort >= fromPort ? toPort : fromPort);
74 }
75 
76 /** Returns true if this policy is identical to <b>policy</b>. */
77 bool
78 Policy::operator==(const Policy &policy) const
79 {
80  return ((this->_action == policy._action) &&
81  (this->_address == policy._address) &&
82  (this->_mask == policy._mask) &&
83  (this->_fromPort == policy._fromPort) &&
84  (this->_toPort == policy._toPort));
85 }
86 
87 /** Returns true if this policy matches <b>policy</b>. For example, if this
88  * policy is "reject *:6660-6669" and <b>policy</b> is "reject *:6662-6664",
89  * this will return true. For strict comparison, use the == operator. */
90 bool
91 Policy::matches(const Policy &policy) const
92 {
93  /* This doesn't take into account addr/mask matches yet */
94  return ((this->_action == policy._action) &&
95  (this->_address == policy._address) &&
96  (this->_mask == policy._mask) &&
97  (this->_fromPort <= policy._fromPort) &&
98  (this->_toPort >= policy._toPort));
99 }
100 
101 /** Parses the given exit policy string. */
102 void
103 Policy::fromString(QString policy)
104 {
105  /* Separate the action and the address/mask/port info */
106  QStringList ruleParts = policy.split(" ");
107  _action = toAction(ruleParts.at(0));
108 
109  /* If some address/mask/port stuff was specified, parse it. */
110  if (ruleParts.size() > 1) {
111  QStringList addrParts = ruleParts.at(1).split(":");
112 
113  /* Parse the address and mask (if specified) */
114  QString addr = addrParts.at(0);
115  _address.setAddress(addr.mid(0, addr.indexOf("/")));
116  if (_address.isNull()) {
117  _address = QHostAddress::Any;
118  }
119  if (addr.contains("/")) {
120  _mask = addr.mid(addr.indexOf("/")+1).toUInt();
121  }
122 
123  /* Parse the specified port range (if specified) */
124  if (addrParts.size() > 1) {
125  QString ports = addrParts.at(1);
126  _fromPort = ports.mid(0, ports.indexOf("-")).toUInt();
127  if (ports.contains("-")) {
128  _toPort = ports.mid(ports.indexOf("-")+1).toUInt();
129  } else {
130  _toPort = _fromPort;
131  }
132  }
133  }
134 }
135 
136 /** Converts this policy to a form Tor understands. The format is:
137  * "accept|reject ADDR[/MASK][:PORT]"
138  *
139  * PORT can be a single port number, an interval of ports "FROM_PORT-TO_PORT",
140  * or "*". If PORT is omitted, that means "*"
141  */
142 QString
144 {
145  QString act = (_action == Accept ? "accept" : "reject");
146  return act + " " + address() + ":" + ports();
147 }
148 
149 /** Converts the given action to a string. This function tolerates both the
150  * translated and untranslated forms of the string "accept" and "reject". */
152 Policy::toAction(QString action)
153 {
154  action = action.toLower();
155  if (action == tr("accept") || action == "accept") {
156  return Accept;
157  }
158  return Reject;
159 }
160 
161 /** Returns the action associated with this policy. NOTE: This string will be
162  * translated to whatever the current language setting is. */
163 QString
165 {
166  return (_action == Accept ? tr("accept") : tr("reject"));
167 }
168 
169 /** Returns the address (and mask, if specified) for this policy. */
170 QString
172 {
173  QString addrString;
174 
175  if (_mask) {
176  addrString = _address.toString() + "/" + QString::number(_mask);
177  } else if (_address == QHostAddress::Any || _address.isNull()) {
178  addrString = "*";
179  } else {
180  addrString = _address.toString();
181  }
182  return addrString;
183 }
184 
185 /** Returns the port (or port range, if specified) for this policy. */
186 QString
188 {
189  QString ports = (_fromPort ? QString::number(_fromPort) : "*");
190  if (_fromPort && (_toPort > _fromPort)) {
191  ports += "-" + QString::number(_toPort);
192  }
193  return ports;
194 }
195