runAsDaemon function to work in the background
[platform/core/security/nether.git] / src / nether_Main.cpp
1 /*
2  *  Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Roman Kubiak (r.kubiak@samsung.com)
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License
17  */
18
19 /**
20  * @file
21  * @author  Roman Kubiak (r.kubiak@samsung.com)
22  * @brief   nether main program
23  */
24
25 #include "nether_Types.h"
26 #include "nether_Utils.h"
27 #include "nether_Manager.h"
28 #include "nether_Daemon.h"
29
30 using namespace std;
31 void showHelp(char *arg);
32
33 int main(int argc, char *argv[])
34 {
35     int optionIndex, c;
36     struct NetherConfig netherConfig;
37
38     static struct option longOptions[] =
39     {
40  #if defined(HAVE_AUDIT)
41           {"enable-audit",          no_argument,        &netherConfig.enableAudit,  0},
42 #endif
43           {"daemon",                    no_argument,            &netherConfig.daemonMode,   0},
44           {"no-rules",              no_argument,        &netherConfig.noRules,      0},
45           {"log",                   required_argument,  0,                          'l'},
46           {"log-args",              required_argument,  0,                          'L'},
47           {"default-verdict",       required_argument,  0,                                          'V'},
48           {"primary-backend",       required_argument,  0,                                          'p'},
49           {"primary-backend-args",  required_argument,  0,                          'P'},
50           {"backup-backend",        required_argument,  0,                                          'b'},
51           {"backup-backend-args",   required_argument,  0,                                          'B'},
52           {"queue-num",                 required_argument,      0,                                          'q'},
53           {"mark-deny",             required_argument,  0,                          'm'},
54           {"mark-allow-log",        required_argument,  0,                          'M'},
55           {"rules-path",            required_argument,  0,                          'r'},
56           {"iptables-restore-path", required_argument,  0,                          'i'},
57           {"help",                          no_argument,                0,                                          'h'},
58           {0, 0, 0, 0}
59     };
60
61     while (1)
62     {
63         c = getopt_long (argc, argv, ":daxl:L:V:p:P:b:B:q:m:M:a:r:i:h", longOptions, &optionIndex);
64
65         if (c == -1)
66             break;
67
68         switch (c)
69         {
70             case 0:
71               break;
72
73             case 'd':
74                 netherConfig.daemonMode             = 1;
75                 break;
76             case 'x':
77                 netherConfig.noRules                = 1;
78                 break;
79
80  #if defined(HAVE_AUDIT)
81             case 'a':
82                 netherConfig.enableAudit            = 1;
83                 break;
84 #endif
85             case 'l':
86                 netherConfig.logBackend             = stringToLogBackendType(optarg);
87                 break;
88
89             case 'L':
90                 netherConfig.logBackendArgs         = optarg;
91                 break;
92
93             case 'V':
94                 netherConfig.defaultVerdict         = stringToVerdict (optarg);
95                 break;
96
97             case 'p':
98                 netherConfig.primaryBackendType     = stringToBackendType (optarg);
99                 break;
100
101             case 'P':
102                 netherConfig.primaryBackendArgs     = optarg;
103                 break;
104
105             case 'b':
106                 netherConfig.backupBackendType      = stringToBackendType (optarg);
107                 break;
108
109             case 'B':
110                 netherConfig.backupBackendArgs      = optarg;
111                 break;
112
113             case 'q':
114                 if (atoi(optarg) < 0 || atoi(optarg) >= 65535)
115                 {
116                     cerr << "Queue number is invalid (must be >= 0 and < 65535): " << atoi(optarg);
117                     exit (1);
118                 }
119                 netherConfig.queueNumber            = atoi(optarg);
120                 break;
121
122             case 'm':
123                 if (atoi(optarg) <= 0 || atoi(optarg) >= 255)
124                 {
125                     cerr << "Packet mark for DENY is invalid (must be > 0 and < 255): " << atoi(optarg);
126                     exit (1);
127                 }
128                 netherConfig.markDeny               = atoi(optarg);
129                 break;
130
131             case 'M':
132                 if (atoi(optarg) <= 0 || atoi(optarg) >= 255)
133                 {
134                     cerr << "Packet mark for ALLOW_LOG is invalid (must be > 0 and < 255): " << atoi(optarg);
135                     exit (1);
136                 }
137                 netherConfig.markAllowAndLog        = atoi(optarg);
138                 break;
139
140             case 'r':
141                 netherConfig.rulesPath              = optarg;
142                 break;
143
144             case 'i':
145                 netherConfig.iptablesRestorePath    = optarg;
146                 break;
147
148             case 'h':
149               showHelp (argv[0]);
150               exit (1);
151         }
152     }
153     switch (netherConfig.logBackend)
154     {
155         case stderrBackend:
156             logger::Logger::setLogBackend (new logger::StderrBackend(false));
157             break;
158         case syslogBackend:
159             logger::Logger::setLogBackend (new logger::SyslogBackend());
160             break;
161         case logfileBackend:
162             logger::Logger::setLogBackend (new logger::FileBackend(netherConfig.logBackendArgs));
163             break;
164 #if defined(HAVE_SYSTEMD_JOURNAL)
165         case journalBackend:
166             logger::Logger::setLogBackend (new logger::SystemdJournalBackend());
167             break;
168 #endif
169         default:
170             logger::Logger::setLogBackend (new logger::StderrBackend(false));
171             break;
172     }
173
174     LOGD("NETHER OPTIONS:"
175 #if defined(_DEBUG)
176         << " debug"
177 #endif
178         << " daemon="                << netherConfig.daemonMode
179         << " queue="                 << netherConfig.queueNumber);
180     LOGD("primary-backend="       << backendTypeToString (netherConfig.primaryBackendType)
181         << " primary-backend-args="  << netherConfig.primaryBackendArgs);
182     LOGD("backup-backend="        << backendTypeToString (netherConfig.backupBackendType)
183         << " backup-backend-args="   << netherConfig.backupBackendArgs);
184     LOGD("default-verdict="       << verdictToString(netherConfig.defaultVerdict)
185         << " mark-deny="             << (int)netherConfig.markDeny
186         << " mark-allow-log="        << (int)netherConfig.markAllowAndLog);
187     LOGD("log-backend="           << logBackendTypeToString(netherConfig.logBackend)
188         << " log-backend-args="      << netherConfig.logBackendArgs);
189     LOGD("enable-audit="          << (netherConfig.enableAudit ? "yes" : "no")
190         << " rules-path="            << netherConfig.rulesPath);
191     LOGD("no-rules="              << (netherConfig.noRules ? "yes" : "no")
192         << " iptables-restore-path=" << netherConfig.iptablesRestorePath);
193
194     NetherManager manager (netherConfig);
195
196     if (!manager.initialize())
197     {
198         LOGE("NetherManager failed to initialize, exiting");
199         return (1);
200     }
201
202     if (netherConfig.daemonMode)
203     {
204         if (!runAsDaemon())
205         {
206             LOGE("Failed to run as daemon: " << strerror(errno));
207             exit (1);
208         }
209     }
210
211     manager.process();
212
213     return (0);
214 }
215
216 void showHelp(char *arg)
217 {
218     cout<< "Usage:\t"<< arg << " [OPTIONS]\n\n";
219     cout<< "  -d,--daemon\t\t\t\tRun as daemon in the background (default:no)\n";
220     cout<< "  -x,--no-rules\t\t\t\tDon't load iptables rules on start (default:no)\n";
221     cout<< "  -l,--log=<backend>\t\t\tSet logging backend STDERR,SYSLOG";
222 #if defined(HAVE_SYSTEMD_JOURNAL)
223     cout << ",JOURNAL\n";
224 #endif
225     cout<< "(default:"<< logBackendTypeToString(NETHER_LOG_BACKEND) << ")\n";
226     cout<< "  -L,--log-args=<arguments>\t\tSet logging backend arguments\n";
227     cout<< "  -V,--verdict=<verdict>\t\tWhat verdict to cast when policy backend is not available\n\t\t\t\t\tACCEPT,ALLOW_LOG,DENY (default:"<<verdictToString(NETHER_DEFAULT_VERDICT)<<")\n";
228     cout<< "  -p,--primary-backend=<module>\t\tPrimary policy backend\n\t\t\t\t\t";
229 #if defined(HAVE_CYNARA)
230     cout << "CYNARA";
231 #endif
232     cout<< ",FILE,NONE (defualt:"<< backendTypeToString(NETHER_PRIMARY_BACKEND)<<")\n";
233     cout<< "  -P,--primary-backend-args=<arguments>\tPrimary policy backend arguments\n";
234     cout<< "  -b,--backup-backend=<module>\t\tBackup policy backend\n\t\t\t\t\t";
235 #if defined(HAVE_CYNARA)
236     cout<< "CYNARA";
237 #endif
238     cout<< ",FILE,NONE (defualt:"<< backendTypeToString(NETHER_BACKUP_BACKEND)<< ")\n";
239     cout<< "  -B,--backup-backend-args=<arguments>\tBackup policy backend arguments (default:" << NETHER_POLICY_FILE << ")\n";
240     cout<< "  -q,--queue-num=<queue number>\t\tNFQUEUE queue number to use for receiving packets\n";
241     cout<< "  -m,--mark-deny=<mark>\t\t\tPacket mark to use for DENY verdicts (default:"<< NETLINK_DROP_MARK << ")\n";
242     cout<< "  -M,--mark-allow-log=<mark>\t\tPacket mark to use for ALLOW_LOG verdicts (default:" << NETLINK_ALLOWLOG_MARK << ")\n";
243 #if defined(HAVE_AUDIT)
244     cout<< "  -a,--enable-audit\t\t\tEnable the auditing subsystem (default: no)\n";
245 #endif
246     cout<< "  -r,--rules-path=<path>\t\tPath to iptables rules file (default:" << NETHER_RULES_PATH << ")\n";
247     cout<< "  -i,--iptables-restore-path=<path>\tPath to iptables-restore command (default:" << NETHER_IPTABLES_RESTORE_PATH << ")\n";
248     cout<< "  -h,--help\t\t\t\tshow help information\n";
249 }