Cherry-picks the code from 0.1.x branch
[rahunas] / src / rh-xmlrpc-server.c
1 /**
2  * RahuNAS XML-RPC Server implementation
3  * Author: Neutron Soutmun <neo.neutron@gmail.com>
4  *         Suriya Soutmun <darksolar@gmail.com>
5  * Date:   2008-08-07
6  */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <pthread.h>
12 #include "rahunasd.h"
13 #include "rh-server.h"
14 #include "rh-xmlrpc-server.h"
15 #include "rh-radius.h"
16 #include "rh-ipset.h"
17 #include "rh-utils.h"
18 #include "rh-task.h"
19 #include "rh-task-memset.h"
20
21 extern const char* termstring;
22
23 int do_startsession(GNetXmlRpcServer *server,
24                     const gchar *command,
25                     const gchar *param,
26                     gpointer user_data,
27                     gchar **reply_string) 
28 {
29   RHMainServer *ms = (RHMainServer *)user_data;
30   RHVServer    *vs = NULL;
31   unsigned char ethernet[ETH_ALEN] = {0,0,0,0,0,0};
32   struct task_req req;
33   gchar *ip = NULL;
34   gchar *username = NULL;
35   gchar *session_id = NULL;
36   gchar *mac_address = NULL;
37   gchar *session_timeout = NULL;
38   gchar *bandwidth_max_down = NULL;
39   gchar *bandwidth_max_up = NULL;
40   gchar *serviceclass_name = NULL;
41   gchar *vserver_id = NULL;
42   uint32_t id;
43   GList *member_node = NULL;
44   struct rahunas_member *member = NULL;
45
46   pthread_mutex_lock (&RHMtxLock);
47
48   if (param == NULL)
49     goto out;
50
51   DP("RPC Receive: %s", param);
52
53   ip          = rh_string_get_sep(param, "|", 1);
54   username    = rh_string_get_sep(param, "|", 2);
55   session_id  = rh_string_get_sep(param, "|", 3);
56   mac_address = rh_string_get_sep(param, "|", 4);
57   session_timeout    = rh_string_get_sep(param, "|", 5);
58   bandwidth_max_down = rh_string_get_sep(param, "|", 6);
59   bandwidth_max_up   = rh_string_get_sep(param, "|", 7);
60   serviceclass_name  = rh_string_get_sep(param, "|", 8);
61   vserver_id         = rh_string_get_sep(param, "|", 9);
62
63   if (ip == NULL || username == NULL || session_id == NULL 
64       || vserver_id == NULL)
65     goto out;
66
67   vs = vserver_get_by_id(ms, atoi(vserver_id));
68
69   if (vs == NULL)
70     goto out;
71
72   if (mac_address == NULL)
73     mac_address = g_strdup(DEFAULT_MAC);
74
75   id = iptoid(vs->v_map, ip);
76
77   if (id < 0) {
78     *reply_string = g_strdup("Invalid IP Address");
79     goto cleanup;
80   }
81
82   /* Check if client already registered */
83   member_node = member_get_node_by_id(vs, id);
84
85   if (member_node != NULL)
86     goto greeting;
87
88   req.id = id;
89   req.vserver_id = atoi(vserver_id);
90   req.username = username;
91   req.session_id = session_id;
92   parse_mac(mac_address, ethernet);
93   memcpy(req.mac_address, ethernet, ETH_ALEN);
94   req.session_start = 0;
95   req.session_timeout = 0;
96
97   if (session_timeout != NULL) {
98     if (atol(session_timeout) != 0)
99       req.session_timeout = time(NULL) + atol(session_timeout);
100   }
101
102   if (bandwidth_max_down != NULL)
103     req.bandwidth_max_down = atol(bandwidth_max_down);
104   else
105     req.bandwidth_max_down = 0;
106
107   if (bandwidth_max_up != NULL)
108     req.bandwidth_max_up = atol(bandwidth_max_up);
109   else
110     req.bandwidth_max_up = 0;
111
112   req.serviceclass_name    = serviceclass_name;
113   req.serviceclass_slot_id = 0;
114
115   rh_task_startsess(vs, &req);
116   member_node = member_get_node_by_id(vs, id);
117
118 greeting:
119   if (member_node != NULL) {
120     member = (struct rahunas_member *)member_node->data;
121     *reply_string = g_strdup_printf("Greeting! Got: IP %s, User %s, ID %s, "
122                                     "Service Class %s, Mapping %s",
123                                     ip, member->username, 
124                                     member->session_id,
125                                     member->serviceclass_name,
126                                     member->mapping_ip);
127     goto cleanup;
128   }
129
130 out:
131   *reply_string = g_strdup("Invalid input parameters");
132
133 cleanup:
134   pthread_mutex_unlock (&RHMtxLock);
135
136   DP("RPC Reply: %s", *reply_string);
137   g_free(ip);
138   g_free(username);
139   g_free(session_id);
140   g_free(mac_address);
141   g_free(session_timeout);
142   g_free(bandwidth_max_down);
143   g_free(bandwidth_max_up);
144   g_free(serviceclass_name);
145   g_free(vserver_id);
146   return 0;
147 }
148
149 int do_stopsession(GNetXmlRpcServer *server,
150                    const gchar *command,
151                    const gchar *param,
152                    gpointer user_data,
153                    gchar **reply_string)
154 {
155   RHMainServer *ms = (RHMainServer *)user_data;
156   RHVServer    *vs = NULL;
157   struct task_req req;
158   gchar *ip = NULL;
159   gchar *mac_address = NULL;
160   gchar *cause = NULL;
161   gchar *vserver_id = NULL;
162   int cause_id = 0;
163   uint32_t   id;
164   int res = 0;
165   unsigned char ethernet[ETH_ALEN] = {0,0,0,0,0,0};
166   GList *member_node = NULL;
167   struct rahunas_member *member = NULL;
168
169   pthread_mutex_lock (&RHMtxLock);
170
171   if (param == NULL)
172     goto out;
173
174   DP("RPC Receive: %s", param);
175
176   ip          = rh_string_get_sep(param, "|", 1);
177   mac_address = rh_string_get_sep(param, "|", 2);
178   cause       = rh_string_get_sep(param, "|", 3);
179   vserver_id  = rh_string_get_sep(param, "|", 4);
180
181   if (ip == NULL || vserver_id == NULL)
182     goto out;
183   vs = vserver_get_by_id(ms, atoi(vserver_id));
184
185   if (vs == NULL)
186     goto out;
187
188   if (mac_address == NULL)
189     mac_address = g_strdup(DEFAULT_MAC);
190
191   id = iptoid(vs->v_map, ip);
192
193   if (id < 0) {
194     *reply_string = g_strdup("Invalid IP Address");
195     goto cleanup;
196   }
197
198   parse_mac(mac_address, ethernet);
199   memcpy(req.mac_address, ethernet, ETH_ALEN);
200
201   member_node = member_get_node_by_id(vs, id);
202
203   if (member_node != NULL) {
204     member = (struct rahunas_member *) member_node->data;
205     if (memcmp(&ethernet, &member->mac_address, 
206         ETH_ALEN) == 0) {
207       req.id = id;
208       
209       if (cause == NULL) {
210         req.req_opt = RH_RADIUS_TERM_USER_REQUEST;
211       } else {
212         cause_id = atoi(cause);
213         if (cause_id >= RH_RADIUS_TERM_USER_REQUEST && 
214             cause_id <= RH_RADIUS_TERM_HOST_REQUEST) {
215           req.req_opt = cause_id;
216         } else {
217           req.req_opt = RH_RADIUS_TERM_USER_REQUEST;
218         }
219       }
220
221       res = rh_task_stopsess(vs, &req);
222       if (res == 0) {
223         *reply_string = g_strdup_printf("Client IP %s was removed!", 
224                                           idtoip(vs->v_map, id));
225       } else {
226          *reply_string = g_strdup_printf("Client IP %s error remove!", 
227                                         idtoip(vs->v_map, id));
228       }
229       goto cleanup;
230     } 
231   }
232
233   *reply_string = g_strdup_printf("%s", ip);
234   goto cleanup;
235
236 out:
237   *reply_string = g_strdup("Invalid input parameters");
238
239 cleanup:
240   pthread_mutex_unlock (&RHMtxLock);
241
242   DP("RPC Reply: %s", *reply_string);
243   g_free(ip);
244   g_free(mac_address);
245   g_free(cause);
246   g_free(vserver_id);
247   return 0;
248 }
249
250 int do_getsessioninfo(GNetXmlRpcServer *server,
251                       const gchar *command,
252                       const gchar *param,
253                       gpointer user_data,
254                       gchar **reply_string)
255 {
256   RHMainServer *ms = (RHMainServer *)user_data;
257   RHVServer    *vs = NULL;
258   gchar *ip = NULL;
259   gchar *vserver_id = NULL;
260   uint32_t   id;
261   GList *member_node = NULL;
262   struct rahunas_member *member = NULL;
263
264   pthread_mutex_lock (&RHMtxLock);
265
266   if (param == NULL)
267     goto out;
268
269   DP("RPC Receive: %s", param);
270
271   ip          = rh_string_get_sep(param, "|", 1);
272   vserver_id  = rh_string_get_sep(param, "|", 2);
273
274   if (ip == NULL || vserver_id == NULL)
275     goto out;
276
277   vs = vserver_get_by_id(ms, atoi(vserver_id));
278
279   if (vs == NULL)
280     goto out;
281
282   id = iptoid(vs->v_map, ip);
283
284   if (id < 0) {
285     *reply_string = g_strdup("Invalid IP Address");
286     goto cleanup;
287   }
288
289   member_node = member_get_node_by_id(vs, id);
290
291   if (member_node != NULL) {
292     member = (struct rahunas_member *) member_node->data;
293     if (!member->username) {
294       *reply_string = g_strdup("Invalid Username");
295       goto cleanup;
296     }
297
298     if (!member->session_id) {
299       *reply_string = g_strdup("Invalid Session ID");
300       goto cleanup;
301     }
302     
303     *reply_string = g_strdup_printf("%s|%s|%s|%d|%s|%d|%s",
304                                     ip, 
305                                     member->username,
306                                     member->session_id,
307                                     member->session_start,
308                                     mac_tostring(member->mac_address),
309                                     member->session_timeout,
310                                     member->serviceclass_description);
311     goto cleanup;
312   }
313
314   *reply_string = g_strdup_printf("%s", ip);
315   goto cleanup;
316
317 out:
318   *reply_string = g_strdup("Invalid input parameters");
319
320 cleanup:
321   pthread_mutex_unlock (&RHMtxLock);
322
323   DP("RPC Reply: %s", *reply_string);
324   g_free(ip);
325   g_free(vserver_id);
326   return 0;
327 }