8d9d7dcb68f1348a36e179b2039dd45e3e59748b
[public/netxms.git] / src / server / core / vpnconn.cpp
1 /*
2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003-2013 Victor Kirhenshtein
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 **
19 ** File: vpnconn.cpp
20 **
21 **/
22
23 #include "nxcore.h"
24
25 /**
26 * Default constructor for VPNConnector object
27 */
28 VPNConnector::VPNConnector() : NetObj()
29 {
30 m_dwPeerGateway = 0;
31 m_localNetworks = new ObjectArray<InetAddress>(8, 8, true);
32 m_remoteNetworks = new ObjectArray<InetAddress>(8, 8, true);
33 }
34
35 /**
36 * Constructor for new VPNConnector object
37 */
38 VPNConnector::VPNConnector(bool hidden) : NetObj()
39 {
40 m_dwPeerGateway = 0;
41 m_localNetworks = new ObjectArray<InetAddress>(8, 8, true);
42 m_remoteNetworks = new ObjectArray<InetAddress>(8, 8, true);
43 m_isHidden = hidden;
44 }
45
46 /**
47 * VPNConnector class destructor
48 */
49 VPNConnector::~VPNConnector()
50 {
51 delete m_localNetworks;
52 delete m_remoteNetworks;
53 }
54
55 /**
56 * Create object from database data
57 */
58 bool VPNConnector::loadFromDatabase(DB_HANDLE hdb, UINT32 dwId)
59 {
60 m_id = dwId;
61
62 if (!loadCommonProperties(hdb))
63 return false;
64
65 // Load network lists
66 TCHAR szQuery[256];
67 _sntprintf(szQuery, 256, _T("SELECT ip_addr,ip_netmask,network_type FROM vpn_connector_networks WHERE vpn_id=%d"), m_id);
68 DB_RESULT hResult = DBSelect(hdb, szQuery);
69 if (hResult == NULL)
70 return false; // Query failed
71 int count = DBGetNumRows(hResult);
72 for(int i = 0; i < count; i++)
73 {
74 InetAddress addr = DBGetFieldInetAddr(hResult, i, 0);
75 addr.setMaskBits(DBGetFieldLong(hResult, i, 1));
76 if (DBGetFieldLong(hResult, i, 2) == 0)
77 m_localNetworks->add(new InetAddress(addr));
78 else
79 m_remoteNetworks->add(new InetAddress(addr));
80 }
81 DBFreeResult(hResult);
82
83 // Load custom properties
84 _sntprintf(szQuery, 256, _T("SELECT node_id,peer_gateway FROM vpn_connectors WHERE id=%d"), dwId);
85 hResult = DBSelect(hdb, szQuery);
86 if (hResult == NULL)
87 return false; // Query failed
88
89 bool success = false;
90 if (DBGetNumRows(hResult) != 0)
91 {
92 UINT32 dwNodeId = DBGetFieldULong(hResult, 0, 0);
93 m_dwPeerGateway = DBGetFieldULong(hResult, 0, 1);
94
95 // Link VPN connector to node
96 if (!m_isDeleted)
97 {
98 NetObj *pObject = FindObjectById(dwNodeId);
99 if (pObject == NULL)
100 {
101 nxlog_write(MSG_INVALID_NODE_ID_EX, NXLOG_ERROR, "dds", dwId, dwNodeId, _T("VPN connector"));
102 }
103 else if (pObject->getObjectClass() != OBJECT_NODE)
104 {
105 nxlog_write(MSG_NODE_NOT_NODE, EVENTLOG_ERROR_TYPE, "dd", dwId, dwNodeId);
106 }
107 else
108 {
109 pObject->addChild(this);
110 addParent(pObject);
111 success = true;
112 }
113 }
114 else
115 {
116 success = true;
117 }
118 }
119
120 DBFreeResult(hResult);
121
122 // Load access list
123 loadACLFromDB(hdb);
124
125 return success;
126 }
127
128 /**
129 * Save VPN connector object to database
130 */
131 bool VPNConnector::saveToDatabase(DB_HANDLE hdb)
132 {
133 // Lock object's access
134 lockProperties();
135
136 saveCommonProperties(hdb);
137
138 // Determine owning node's ID
139 Node *pNode = getParentNode();
140 UINT32 dwNodeId = (pNode != NULL) ? pNode->getId() : 0;
141
142 // Form and execute INSERT or UPDATE query
143 TCHAR szQuery[1024];
144 if (IsDatabaseRecordExist(hdb, _T("vpn_connectors"), _T("id"), m_id))
145 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("UPDATE vpn_connectors SET node_id=%d,peer_gateway=%d WHERE id=%d"),
146 dwNodeId, m_dwPeerGateway, m_id);
147 else
148 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("INSERT INTO vpn_connectors (id,node_id,peer_gateway) VALUES (%d,%d,%d)"),
149 m_id, dwNodeId, m_dwPeerGateway);
150 DBQuery(hdb, szQuery);
151
152 // Save network list
153 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("DELETE FROM vpn_connector_networks WHERE vpn_id=%d"), m_id);
154 DBQuery(hdb, szQuery);
155
156 int i;
157 TCHAR buffer[64];
158 for(i = 0; i < m_localNetworks->size(); i++)
159 {
160 InetAddress *addr = m_localNetworks->get(i);
161 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR),
162 _T("INSERT INTO vpn_connector_networks (vpn_id,network_type,ip_addr,ip_netmask) VALUES (%d,0,'%s',%d)"),
163 (int)m_id, addr->toString(buffer), addr->getMaskBits());
164 DBQuery(hdb, szQuery);
165 }
166 for(i = 0; i < m_remoteNetworks->size(); i++)
167 {
168 InetAddress *addr = m_remoteNetworks->get(i);
169 _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR),
170 _T("INSERT INTO vpn_connector_networks (vpn_id,network_type,ip_addr,ip_netmask) VALUES (%d,1,'%s',%d)"),
171 (int)m_id, addr->toString(buffer), addr->getMaskBits());
172 DBQuery(hdb, szQuery);
173 }
174
175 // Save access list
176 saveACLToDB(hdb);
177
178 // Clear modifications flag and unlock object
179 m_isModified = false;
180 unlockProperties();
181
182 return true;
183 }
184
185 /**
186 * Delete VPN connector object from database
187 */
188 bool VPNConnector::deleteFromDatabase(DB_HANDLE hdb)
189 {
190 bool success = NetObj::deleteFromDatabase(hdb);
191 if (success)
192 success = executeQueryOnObject(hdb, _T("DELETE FROM vpn_connectors WHERE id=?"));
193 if (success)
194 success = executeQueryOnObject(hdb, _T("DELETE FROM vpn_connector_networks WHERE vpn_id=?"));
195 return success;
196 }
197
198 /**
199 * Get connector's parent node
200 */
201 Node *VPNConnector::getParentNode()
202 {
203 Node *pNode = NULL;
204
205 lockParentList(false);
206 for(int i = 0; i < m_parentList->size(); i++)
207 {
208 NetObj *object = m_parentList->get(i);
209 if (object->getObjectClass() == OBJECT_NODE)
210 {
211 pNode = (Node *)object;
212 break;
213 }
214 }
215 unlockParentList();
216 return pNode;
217 }
218
219 /**
220 * Create NXCP message with object's data
221 */
222 void VPNConnector::fillMessageInternal(NXCPMessage *pMsg)
223 {
224 NetObj::fillMessageInternal(pMsg);
225 pMsg->setField(VID_PEER_GATEWAY, m_dwPeerGateway);
226 pMsg->setField(VID_NUM_LOCAL_NETS, (UINT32)m_localNetworks->size());
227 pMsg->setField(VID_NUM_REMOTE_NETS, (UINT32)m_remoteNetworks->size());
228
229 UINT32 fieldId;
230 int i;
231
232 for(i = 0, fieldId = VID_VPN_NETWORK_BASE; i < m_localNetworks->size(); i++)
233 pMsg->setField(fieldId++, *m_localNetworks->get(i));
234
235 for(i = 0; i < m_remoteNetworks->size(); i++)
236 pMsg->setField(fieldId++, *m_remoteNetworks->get(i));
237 }
238
239 /**
240 * Modify object from message
241 */
242 UINT32 VPNConnector::modifyFromMessageInternal(NXCPMessage *pRequest)
243 {
244 // Peer gateway
245 if (pRequest->isFieldExist(VID_PEER_GATEWAY))
246 m_dwPeerGateway = pRequest->getFieldAsUInt32(VID_PEER_GATEWAY);
247
248 // Network list
249 if ((pRequest->isFieldExist(VID_NUM_LOCAL_NETS)) &&
250 (pRequest->isFieldExist(VID_NUM_REMOTE_NETS)))
251 {
252 int i;
253 UINT32 fieldId = VID_VPN_NETWORK_BASE;
254
255 m_localNetworks->clear();
256 int count = pRequest->getFieldAsInt32(VID_NUM_LOCAL_NETS);
257 for(i = 0; i < count; i++)
258 m_localNetworks->add(new InetAddress(pRequest->getFieldAsInetAddress(fieldId++)));
259
260 m_remoteNetworks->clear();
261 count = pRequest->getFieldAsInt32(VID_NUM_REMOTE_NETS);
262 for(i = 0; i < count; i++)
263 m_remoteNetworks->add(new InetAddress(pRequest->getFieldAsInetAddress(fieldId++)));
264 }
265
266 return NetObj::modifyFromMessageInternal(pRequest);
267 }
268
269 /**
270 * Check if given address falls into one of the local nets
271 */
272 bool VPNConnector::isLocalAddr(const InetAddress& addr)
273 {
274 bool result = false;
275
276 lockProperties();
277
278 for(int i = 0; i < m_localNetworks->size(); i++)
279 if (m_localNetworks->get(i)->contain(addr))
280 {
281 result = true;
282 break;
283 }
284
285 unlockProperties();
286 return result;
287 }
288
289 /**
290 * Check if given address falls into one of the remote nets
291 */
292 bool VPNConnector::isRemoteAddr(const InetAddress& addr)
293 {
294 bool result = false;
295
296 lockProperties();
297
298 for(int i = 0; i < m_remoteNetworks->size(); i++)
299 if (m_remoteNetworks->get(i)->contain(addr))
300 {
301 result = true;
302 break;
303 }
304
305 unlockProperties();
306 return result;
307 }
308
309 /**
310 * Get address of peer gateway
311 */
312 InetAddress VPNConnector::getPeerGatewayAddr()
313 {
314 NetObj *pObject;
315
316 pObject = FindObjectById(m_dwPeerGateway);
317 if (pObject != NULL)
318 {
319 if (pObject->getObjectClass() == OBJECT_NODE)
320 return ((Node *)pObject)->getIpAddress();
321 }
322 return InetAddress();
323 }
324
325 /**
326 * Serialize object to JSON
327 */
328 json_t *VPNConnector::toJson()
329 {
330 json_t *root = NetObj::toJson();
331 json_object_set_new(root, "peerGateway", json_integer(m_dwPeerGateway));
332 json_object_set_new(root, "localNetworks", json_object_array(m_localNetworks));
333 json_object_set_new(root, "remoteNetworks", json_object_array(m_remoteNetworks));
334 return root;
335 }