Cherry-picks the code from 0.1.x branch
[rahunas] / src / rh-task-iptables.c
1 /**
2  * RahuNAS task bandwidth implementation 
3  * Author: Neutron Soutmun <neo.neutron@gmail.com>
4  * Date:   2008-11-20
5  */
6
7 #include <stdlib.h>
8 #include <string.h>
9 #include <syslog.h>
10 #include <sys/types.h>
11 #include <unistd.h>
12 #include <sys/wait.h>
13 #include <sys/stat.h>
14 #include <fcntl.h>
15
16 #include "rahunasd.h"
17 #include "rh-task.h"
18 #include "rh-utils.h"
19
20 int iptables_exec(RHVServer *vs, char *const args[])
21 {
22   pid_t ws;
23   pid_t pid;
24   int status;
25   int exec_pipe[2];
26   char buffer[150];
27   char *endline = NULL;
28   int ret = 0;
29   int fd = 0;
30   int i = 0;
31   char *env[22];
32   int env_size = (sizeof (env) / sizeof (char *));
33
34   env[0]  = g_strdup("ENV_OVERRIDE=yes");
35   env[1]  = g_strdup_printf("SETNAME=%s", vs->vserver_config->vserver_name);
36   env[2]  = g_strdup_printf("VSERVER_ID=%d", vs->vserver_config->vserver_id);
37   env[3]  = g_strdup_printf("DEV_EXTERNAL=%s",vs->vserver_config->dev_external);
38   env[4]  = g_strdup_printf("DEV_INTERNAL=%s",vs->vserver_config->dev_internal);
39   env[5]  = g_strdup_printf("BRIDGE=%s", vs->vserver_config->bridge);
40   env[6]  = g_strdup_printf("MASQUERADE=%s", vs->vserver_config->masquerade);
41   env[7]  = g_strdup_printf("IGNORE_MAC=%s", vs->vserver_config->ignore_mac);
42   env[8]  = g_strdup_printf("VSERVER_IP=%s", vs->vserver_config->vserver_ip);
43   env[9]  = g_strdup_printf("CLIENTS=%s", vs->vserver_config->clients);
44   env[10] = g_strdup_printf("EXCLUDED=%s", vs->vserver_config->excluded);
45   env[11] = g_strdup_printf("DNS=%s", vs->vserver_config->dns);
46   env[12] = g_strdup_printf("SSH=%s", vs->vserver_config->ssh);
47   env[13] = g_strdup_printf("PROXY=%s", vs->vserver_config->proxy);
48   env[14] = g_strdup_printf("PROXY_HOST=%s", vs->vserver_config->proxy_host);
49   env[15] = g_strdup_printf("PROXY_PORT=%s", vs->vserver_config->proxy_port);
50   env[16] = g_strdup_printf("BITTORRENT=%s", vs->vserver_config->bittorrent);
51   env[17] = g_strdup_printf("BITTORRENT_ALLOW=%s", 
52                             vs->vserver_config->bittorrent_allow);
53   env[18] = g_strdup_printf("VSERVER_PORTS_ALLOW=%s", 
54                             vs->vserver_config->vserver_ports_allow);
55   env[19] = g_strdup_printf("VSERVER_PORTS_INTERCEPT=%s", 
56                             vs->vserver_config->vserver_ports_intercept);
57   env[20] = g_strdup_printf("KEEP_SET=%s",
58                             vs->vserver_config->init_flag == VS_RELOAD ?
59                             "yes" : "no");
60   env[21] = (char *) 0;
61
62   for (i = 0; i < env_size; i++) {
63     if (env[i] != NULL) 
64       DP("%s", env[i]);
65   }
66   
67   memset(buffer, '\0', sizeof(buffer));
68
69   if (pipe(exec_pipe) == -1) {
70     logmsg(RH_LOG_ERROR, "Error: pipe()");
71     return -1;
72   }
73   DP("pipe0=%d,pipe1=%d", exec_pipe[0], exec_pipe[1]);
74
75   pid = vfork();
76   dup2(exec_pipe[1], STDOUT_FILENO);
77
78   if (pid == 0) {
79     // Child
80     execve(RAHUNAS_FIREWALL_WRAPPER, args, env);
81   } else if (pid < 0) {
82     // Fork error
83     logmsg(RH_LOG_ERROR, "Error: vfork()"); 
84     ret = -1;
85   } else {
86     // Parent
87     ws = waitpid(pid, &status, 0);
88
89     DP("IPTables: Return (%d)", WEXITSTATUS(status));
90
91     if (WIFEXITED(status)) {
92       ret = WEXITSTATUS(status);
93     } else {
94       ret = -1;
95     } 
96   }
97
98   close(exec_pipe[0]);
99   close(exec_pipe[1]);
100
101  
102   for (i = 0; i < env_size; i++) {
103     g_free(env[i]);
104   } 
105   
106   return ret;
107 }
108
109 int iptables_start(RHVServer *vs)
110 {
111   char *args[3];
112
113   DP("IPTables: start");
114
115   args[0] = RAHUNAS_FIREWALL_WRAPPER;
116   args[1] = "start-config";
117   args[2] = (char *) 0;
118
119   return iptables_exec(vs, args);
120 }
121
122 int iptables_stop(RHVServer *vs)
123 {
124   char *args[3];
125
126   DP("IPTables: stop");
127
128   args[0] = RAHUNAS_FIREWALL_WRAPPER;
129   args[1] = "stop-config";
130   args[2] = (char *) 0;
131
132   return iptables_exec(vs, args);
133 }
134
135 /* Start service task */
136 static int startservice ()
137 {
138   return 0;
139 }
140
141 /* Stop service task */
142 static int stopservice  ()
143 {
144   return 0;
145 }
146
147 /* Initialize */
148 static void init (RHVServer *vs)
149 {
150   logmsg(RH_LOG_NORMAL, "[%s] Task IPTABLES initialize..", 
151          vs->vserver_config->vserver_name);  
152
153   iptables_start(vs);
154 }
155
156 /* Cleanup */
157 static void cleanup (RHVServer *vs)
158 {
159   logmsg(RH_LOG_NORMAL, "[%s] Task IPTABLES cleanup..",
160          vs->vserver_config->vserver_name);  
161
162   iptables_stop(vs);
163 }
164
165 /* Start session task */
166 static int startsess (RHVServer *vs, struct task_req *req)
167 {
168   /* Do nothing */
169   return 0;
170 }
171
172 /* Stop session task */
173 static int stopsess  (RHVServer *vs, struct task_req *req)
174 {
175   /* Do nothing */
176   return 0; 
177 }
178
179 /* Commit start session task */
180 static int commitstartsess (RHVServer *vs, struct task_req *req)
181 {
182   /* Do nothing or need to implement */
183 }
184
185 /* Commit stop session task */
186 static int commitstopsess  (RHVServer *vs, struct task_req *req)
187 {
188   /* Do nothing or need to implement */
189 }
190
191 /* Rollback start session task */
192 static int rollbackstartsess (RHVServer *vs, struct task_req *req)
193 {
194   /* Do nothing or need to implement */
195 }
196
197 /* Rollback stop session task */
198 static int rollbackstopsess  (RHVServer *vs, struct task_req *req)
199 {
200   /* Do nothing or need to implement */
201 }
202
203 static struct task taskiptables = {
204   .taskname = "IPTABLES",
205   .taskprio = 50,
206   .init = &init,
207   .cleanup = &cleanup,
208   .startservice = &startservice,
209   .stopservice = &stopservice,
210   .startsess = &startsess,
211   .stopsess = &stopsess,
212   .commitstartsess = &commitstartsess,
213   .commitstopsess = &commitstopsess,
214   .rollbackstartsess = &rollbackstartsess,
215   .rollbackstopsess = &rollbackstopsess,
216 };
217
218 void rh_task_iptables_reg(RHMainServer *ms) {
219   task_register(ms, &taskiptables);
220 }