aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2016-03-18 08:48:24 -0400
committerLibravatar netblue30 <netblue30@yahoo.com>2016-03-18 08:48:24 -0400
commit2671d62cdec158aab13aa583523e8662821e5e5e (patch)
tree75c53ecee26747cd3fe2d4bd9043aad831045fde /src
parentjoin fixes (diff)
downloadfirejail-2671d62cdec158aab13aa583523e8662821e5e5e.tar.gz
firejail-2671d62cdec158aab13aa583523e8662821e5e5e.tar.zst
firejail-2671d62cdec158aab13aa583523e8662821e5e5e.zip
run time networking support
Diffstat (limited to 'src')
-rw-r--r--src/firejail/checkcfg.c19
-rw-r--r--src/firejail/firejail.h4
-rw-r--r--src/firejail/main.c564
-rw-r--r--src/firejail/profile.c46
4 files changed, 392 insertions, 241 deletions
diff --git a/src/firejail/checkcfg.c b/src/firejail/checkcfg.c
index 8376cd9af..df0e1a8e1 100644
--- a/src/firejail/checkcfg.c
+++ b/src/firejail/checkcfg.c
@@ -35,6 +35,7 @@ int checkcfg(int val) {
35 int i; 35 int i;
36 for (i = 0; i < CFG_MAX; i++) 36 for (i = 0; i < CFG_MAX; i++)
37 cfg_val[i] = 1; // most of them are enabled by default 37 cfg_val[i] = 1; // most of them are enabled by default
38 cfg_val[CFG_RESTRICTED_NETWORK] = 0; // disabled by default
38 39
39 // open configuration file 40 // open configuration file
40 char *fname; 41 char *fname;
@@ -113,6 +114,24 @@ int checkcfg(int val) {
113 else 114 else
114 goto errout; 115 goto errout;
115 } 116 }
117 // network
118 else if (strncmp(ptr, "network ", 8) == 0) {
119 if (strcmp(ptr + 8, "yes") == 0)
120 cfg_val[CFG_NETWORK] = 1;
121 else if (strcmp(ptr + 8, "no") == 0)
122 cfg_val[CFG_NETWORK] = 0;
123 else
124 goto errout;
125 }
126 // network
127 else if (strncmp(ptr, "restricted-network ", 19) == 0) {
128 if (strcmp(ptr + 19, "yes") == 0)
129 cfg_val[CFG_RESTRICTED_NETWORK] = 1;
130 else if (strcmp(ptr + 19, "no") == 0)
131 cfg_val[CFG_RESTRICTED_NETWORK] = 0;
132 else
133 goto errout;
134 }
116 else 135 else
117 goto errout; 136 goto errout;
118 free(ptr); 137 free(ptr);
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 2b2912b3e..f1ddd40ad 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -544,7 +544,9 @@ void sandboxfs(int op, pid_t pid, const char *patqh);
544#define CFG_USERNS 3 544#define CFG_USERNS 3
545#define CFG_CHROOT 4 545#define CFG_CHROOT 4
546#define CFG_SECCOMP 5 546#define CFG_SECCOMP 5
547#define CFG_MAX 6 // this should always be the last entry 547#define CFG_NETWORK 6
548#define CFG_RESTRICTED_NETWORK 7
549#define CFG_MAX 8 // this should always be the last entry
548int checkcfg(int val); 550int checkcfg(int val);
549 551
550#endif 552#endif
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 02a55ac70..b20854b30 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -290,63 +290,69 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
290#endif 290#endif
291#ifdef HAVE_NETWORK 291#ifdef HAVE_NETWORK
292 else if (strncmp(argv[i], "--bandwidth=", 12) == 0) { 292 else if (strncmp(argv[i], "--bandwidth=", 12) == 0) {
293 logargs(argc, argv); 293 if (checkcfg(CFG_NETWORK)) {
294 294 logargs(argc, argv);
295 // extract the command 295
296 if ((i + 1) == argc) { 296 // extract the command
297 fprintf(stderr, "Error: command expected after --bandwidth option\n"); 297 if ((i + 1) == argc) {
298 exit(1); 298 fprintf(stderr, "Error: command expected after --bandwidth option\n");
299 }
300 char *cmd = argv[i + 1];
301 if (strcmp(cmd, "status") && strcmp(cmd, "clear") && strcmp(cmd, "set")) {
302 fprintf(stderr, "Error: invalid --bandwidth command.\nValid commands: set, clear, status.\n");
303 exit(1);
304 }
305
306 // extract network name
307 char *dev = NULL;
308 int down = 0;
309 int up = 0;
310 if (strcmp(cmd, "set") == 0 || strcmp(cmd, "clear") == 0) {
311 // extract device name
312 if ((i + 2) == argc) {
313 fprintf(stderr, "Error: network name expected after --bandwidth %s option\n", cmd);
314 exit(1); 299 exit(1);
315 } 300 }
316 dev = argv[i + 2]; 301 char *cmd = argv[i + 1];
317 302 if (strcmp(cmd, "status") && strcmp(cmd, "clear") && strcmp(cmd, "set")) {
318 // check device name 303 fprintf(stderr, "Error: invalid --bandwidth command.\nValid commands: set, clear, status.\n");
319 if (if_nametoindex(dev) == 0) {
320 fprintf(stderr, "Error: network device %s not found\n", dev);
321 exit(1); 304 exit(1);
322 } 305 }
323 306
324 // extract bandwidth 307 // extract network name
325 if (strcmp(cmd, "set") == 0) { 308 char *dev = NULL;
326 if ((i + 4) >= argc) { 309 int down = 0;
327 fprintf(stderr, "Error: invalid --bandwidth set command\n"); 310 int up = 0;
311 if (strcmp(cmd, "set") == 0 || strcmp(cmd, "clear") == 0) {
312 // extract device name
313 if ((i + 2) == argc) {
314 fprintf(stderr, "Error: network name expected after --bandwidth %s option\n", cmd);
328 exit(1); 315 exit(1);
329 } 316 }
330 317 dev = argv[i + 2];
331 down = atoi(argv[i + 3]); 318
332 if (down < 0) { 319 // check device name
333 fprintf(stderr, "Error: invalid download speed\n"); 320 if (if_nametoindex(dev) == 0) {
321 fprintf(stderr, "Error: network device %s not found\n", dev);
334 exit(1); 322 exit(1);
335 } 323 }
336 up = atoi(argv[i + 4]); 324
337 if (up < 0) { 325 // extract bandwidth
338 fprintf(stderr, "Error: invalid upload speed\n"); 326 if (strcmp(cmd, "set") == 0) {
339 exit(1); 327 if ((i + 4) >= argc) {
328 fprintf(stderr, "Error: invalid --bandwidth set command\n");
329 exit(1);
330 }
331
332 down = atoi(argv[i + 3]);
333 if (down < 0) {
334 fprintf(stderr, "Error: invalid download speed\n");
335 exit(1);
336 }
337 up = atoi(argv[i + 4]);
338 if (up < 0) {
339 fprintf(stderr, "Error: invalid upload speed\n");
340 exit(1);
341 }
340 } 342 }
341 } 343 }
342 } 344
343 345 // extract pid or sandbox name
344 // extract pid or sandbox name 346 pid_t pid;
345 pid_t pid; 347 if (read_pid(argv[i] + 12, &pid) == 0)
346 if (read_pid(argv[i] + 12, &pid) == 0) 348 bandwidth_pid(pid, cmd, dev, down, up);
347 bandwidth_pid(pid, cmd, dev, down, up); 349 else
348 else 350 bandwidth_name(argv[i] + 12, cmd, dev, down, up);
349 bandwidth_name(argv[i] + 12, cmd, dev, down, up); 351 }
352 else {
353 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n");
354 exit(1);
355 }
350 exit(0); 356 exit(0);
351 } 357 }
352#endif 358#endif
@@ -454,7 +460,13 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
454 } 460 }
455#ifdef HAVE_NETWORK 461#ifdef HAVE_NETWORK
456 else if (strcmp(argv[i], "--netstats") == 0) { 462 else if (strcmp(argv[i], "--netstats") == 0) {
457 netstats(); 463 if (checkcfg(CFG_NETWORK)) {
464 netstats();
465 }
466 else {
467 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n");
468 exit(1);
469 }
458 exit(0); 470 exit(0);
459 } 471 }
460#endif 472#endif
@@ -531,19 +543,26 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
531 } 543 }
532#ifdef HAVE_NETWORK 544#ifdef HAVE_NETWORK
533 else if (strncmp(argv[i], "--join-network=", 15) == 0) { 545 else if (strncmp(argv[i], "--join-network=", 15) == 0) {
534 logargs(argc, argv); 546 if (checkcfg(CFG_NETWORK)) {
535 arg_join_network = 1; 547 logargs(argc, argv);
536 if (getuid() != 0) { 548 arg_join_network = 1;
537 fprintf(stderr, "Error: --join-network is only available to root user\n"); 549 if (getuid() != 0) {
550 fprintf(stderr, "Error: --join-network is only available to root user\n");
551 exit(1);
552 }
553
554 // join sandbox by pid or by name
555 pid_t pid;
556 if (read_pid(argv[i] + 15, &pid) == 0)
557 join(pid, argc, argv, i + 1);
558 else
559 join_name(argv[i] + 15, argc, argv, i + 1);
560 }
561 else {
562 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n");
538 exit(1); 563 exit(1);
539 } 564 }
540 565
541 // join sandbox by pid or by name
542 pid_t pid;
543 if (read_pid(argv[i] + 15, &pid) == 0)
544 join(pid, argc, argv, i + 1);
545 else
546 join_name(argv[i] + 15, argc, argv, i + 1);
547 exit(0); 566 exit(0);
548 } 567 }
549#endif 568#endif
@@ -1277,204 +1296,278 @@ int main(int argc, char **argv) {
1277 //************************************* 1296 //*************************************
1278#ifdef HAVE_NETWORK 1297#ifdef HAVE_NETWORK
1279 else if (strncmp(argv[i], "--interface=", 12) == 0) { 1298 else if (strncmp(argv[i], "--interface=", 12) == 0) {
1299 if (checkcfg(CFG_NETWORK)) {
1280#ifdef HAVE_NETWORK_RESTRICTED 1300#ifdef HAVE_NETWORK_RESTRICTED
1281 if (getuid() != 0) { 1301 // compile time restricted networking
1282 fprintf(stderr, "Error: --interface is allowed only to root user\n"); 1302 if (getuid() != 0) {
1283 exit(1); 1303 fprintf(stderr, "Error: --interface is allowed only to root user\n");
1284 } 1304 exit(1);
1305 }
1285#endif 1306#endif
1286 // checks 1307 // run time restricted networking
1287 if (arg_nonetwork) { 1308 if (checkcfg(CFG_RESTRICTED_NETWORK) && getuid() != 0) {
1288 fprintf(stderr, "Error: --network=none and --interface are incompatible\n"); 1309 fprintf(stderr, "Error: --interface is allowed only to root user\n");
1289 exit(1); 1310 exit(1);
1290 } 1311 }
1291 if (strcmp(argv[i] + 12, "lo") == 0) { 1312
1292 fprintf(stderr, "Error: cannot use lo device in --interface command\n"); 1313 // checks
1293 exit(1); 1314 if (arg_nonetwork) {
1294 } 1315 fprintf(stderr, "Error: --network=none and --interface are incompatible\n");
1295 int ifindex = if_nametoindex(argv[i] + 12); 1316 exit(1);
1296 if (ifindex <= 0) { 1317 }
1297 fprintf(stderr, "Error: cannot find interface %s\n", argv[i] + 12); 1318 if (strcmp(argv[i] + 12, "lo") == 0) {
1298 exit(1); 1319 fprintf(stderr, "Error: cannot use lo device in --interface command\n");
1320 exit(1);
1321 }
1322 int ifindex = if_nametoindex(argv[i] + 12);
1323 if (ifindex <= 0) {
1324 fprintf(stderr, "Error: cannot find interface %s\n", argv[i] + 12);
1325 exit(1);
1326 }
1327
1328 Interface *intf;
1329 if (cfg.interface0.configured == 0)
1330 intf = &cfg.interface0;
1331 else if (cfg.interface1.configured == 0)
1332 intf = &cfg.interface1;
1333 else if (cfg.interface2.configured == 0)
1334 intf = &cfg.interface2;
1335 else if (cfg.interface3.configured == 0)
1336 intf = &cfg.interface3;
1337 else {
1338 fprintf(stderr, "Error: maximum 4 interfaces are allowed\n");
1339 return 1;
1340 }
1341
1342 intf->dev = strdup(argv[i] + 12);
1343 if (!intf->dev)
1344 errExit("strdup");
1345
1346 if (net_get_if_addr(intf->dev, &intf->ip, &intf->mask, intf->mac, &intf->mtu)) {
1347 fprintf(stderr, "Warning: interface %s is not configured\n", intf->dev);
1348 }
1349 intf->configured = 1;
1299 } 1350 }
1300
1301 Interface *intf;
1302 if (cfg.interface0.configured == 0)
1303 intf = &cfg.interface0;
1304 else if (cfg.interface1.configured == 0)
1305 intf = &cfg.interface1;
1306 else if (cfg.interface2.configured == 0)
1307 intf = &cfg.interface2;
1308 else if (cfg.interface3.configured == 0)
1309 intf = &cfg.interface3;
1310 else { 1351 else {
1311 fprintf(stderr, "Error: maximum 4 interfaces are allowed\n"); 1352 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n");
1312 return 1; 1353 exit(1);
1313 }
1314
1315 intf->dev = strdup(argv[i] + 12);
1316 if (!intf->dev)
1317 errExit("strdup");
1318
1319 if (net_get_if_addr(intf->dev, &intf->ip, &intf->mask, intf->mac, &intf->mtu)) {
1320 fprintf(stderr, "Warning: interface %s is not configured\n", intf->dev);
1321 } 1354 }
1322 intf->configured = 1;
1323 } 1355 }
1356
1324 else if (strncmp(argv[i], "--net=", 6) == 0) { 1357 else if (strncmp(argv[i], "--net=", 6) == 0) {
1325 if (strcmp(argv[i] + 6, "none") == 0) { 1358 if (checkcfg(CFG_NETWORK)) {
1326 arg_nonetwork = 1; 1359 if (strcmp(argv[i] + 6, "none") == 0) {
1327 cfg.bridge0.configured = 0; 1360 arg_nonetwork = 1;
1328 cfg.bridge1.configured = 0; 1361 cfg.bridge0.configured = 0;
1329 cfg.bridge2.configured = 0; 1362 cfg.bridge1.configured = 0;
1330 cfg.bridge3.configured = 0; 1363 cfg.bridge2.configured = 0;
1331 cfg.interface0.configured = 0; 1364 cfg.bridge3.configured = 0;
1332 cfg.interface1.configured = 0; 1365 cfg.interface0.configured = 0;
1333 cfg.interface2.configured = 0; 1366 cfg.interface1.configured = 0;
1334 cfg.interface3.configured = 0; 1367 cfg.interface2.configured = 0;
1335 continue; 1368 cfg.interface3.configured = 0;
1336 } 1369 continue;
1370 }
1371
1337#ifdef HAVE_NETWORK_RESTRICTED 1372#ifdef HAVE_NETWORK_RESTRICTED
1338 if (getuid() != 0) { 1373 // compile time restricted networking
1339 fprintf(stderr, "Error: only --net=none is allowed to non-root users\n"); 1374 if (getuid() != 0) {
1340 exit(1); 1375 fprintf(stderr, "Error: only --net=none is allowed to non-root users\n");
1341 } 1376 exit(1);
1377 }
1342#endif 1378#endif
1343 if (strcmp(argv[i] + 6, "lo") == 0) { 1379 // run time restricted networking
1344 fprintf(stderr, "Error: cannot attach to lo device\n"); 1380 if (checkcfg(CFG_RESTRICTED_NETWORK) && getuid() != 0) {
1345 exit(1); 1381 fprintf(stderr, "Error: only --net=none is allowed to non-root users\n");
1382 exit(1);
1383 }
1384 if (strcmp(argv[i] + 6, "lo") == 0) {
1385 fprintf(stderr, "Error: cannot attach to lo device\n");
1386 exit(1);
1387 }
1388
1389 Bridge *br;
1390 if (cfg.bridge0.configured == 0)
1391 br = &cfg.bridge0;
1392 else if (cfg.bridge1.configured == 0)
1393 br = &cfg.bridge1;
1394 else if (cfg.bridge2.configured == 0)
1395 br = &cfg.bridge2;
1396 else if (cfg.bridge3.configured == 0)
1397 br = &cfg.bridge3;
1398 else {
1399 fprintf(stderr, "Error: maximum 4 network devices are allowed\n");
1400 return 1;
1401 }
1402 net_configure_bridge(br, argv[i] + 6);
1346 } 1403 }
1347
1348 Bridge *br;
1349 if (cfg.bridge0.configured == 0)
1350 br = &cfg.bridge0;
1351 else if (cfg.bridge1.configured == 0)
1352 br = &cfg.bridge1;
1353 else if (cfg.bridge2.configured == 0)
1354 br = &cfg.bridge2;
1355 else if (cfg.bridge3.configured == 0)
1356 br = &cfg.bridge3;
1357 else { 1404 else {
1358 fprintf(stderr, "Error: maximum 4 network devices are allowed\n"); 1405 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n");
1359 return 1; 1406 exit(1);
1360 } 1407 }
1361 net_configure_bridge(br, argv[i] + 6);
1362 } 1408 }
1409
1363 else if (strcmp(argv[i], "--scan") == 0) { 1410 else if (strcmp(argv[i], "--scan") == 0) {
1364 arg_scan = 1; 1411 if (checkcfg(CFG_NETWORK)) {
1365 } 1412 arg_scan = 1;
1366 else if (strncmp(argv[i], "--iprange=", 10) == 0) {
1367 Bridge *br = last_bridge_configured();
1368 if (br == NULL) {
1369 fprintf(stderr, "Error: no network device configured\n");
1370 return 1;
1371 } 1413 }
1372 if (br->iprange_start || br->iprange_end) { 1414 else {
1373 fprintf(stderr, "Error: cannot configure the IP range twice for the same interface\n"); 1415 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n");
1374 return 1; 1416 exit(1);
1375 } 1417 }
1376 1418 }
1377 // parse option arguments 1419 else if (strncmp(argv[i], "--iprange=", 10) == 0) {
1378 char *firstip = argv[i] + 10; 1420 if (checkcfg(CFG_NETWORK)) {
1379 char *secondip = firstip; 1421 Bridge *br = last_bridge_configured();
1380 while (*secondip != '\0') { 1422 if (br == NULL) {
1381 if (*secondip == ',') 1423 fprintf(stderr, "Error: no network device configured\n");
1382 break; 1424 return 1;
1425 }
1426 if (br->iprange_start || br->iprange_end) {
1427 fprintf(stderr, "Error: cannot configure the IP range twice for the same interface\n");
1428 return 1;
1429 }
1430
1431 // parse option arguments
1432 char *firstip = argv[i] + 10;
1433 char *secondip = firstip;
1434 while (*secondip != '\0') {
1435 if (*secondip == ',')
1436 break;
1437 secondip++;
1438 }
1439 if (*secondip == '\0') {
1440 fprintf(stderr, "Error: invalid IP range\n");
1441 return 1;
1442 }
1443 *secondip = '\0';
1383 secondip++; 1444 secondip++;
1445
1446 // check addresses
1447 if (atoip(firstip, &br->iprange_start) || atoip(secondip, &br->iprange_end) ||
1448 br->iprange_start >= br->iprange_end) {
1449 fprintf(stderr, "Error: invalid IP range\n");
1450 return 1;
1451 }
1452 if (in_netrange(br->iprange_start, br->ip, br->mask) || in_netrange(br->iprange_end, br->ip, br->mask)) {
1453 fprintf(stderr, "Error: IP range addresses not in network range\n");
1454 return 1;
1455 }
1384 } 1456 }
1385 if (*secondip == '\0') { 1457 else {
1386 fprintf(stderr, "Error: invalid IP range\n"); 1458 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n");
1387 return 1; 1459 exit(1);
1388 }
1389 *secondip = '\0';
1390 secondip++;
1391
1392 // check addresses
1393 if (atoip(firstip, &br->iprange_start) || atoip(secondip, &br->iprange_end) ||
1394 br->iprange_start >= br->iprange_end) {
1395 fprintf(stderr, "Error: invalid IP range\n");
1396 return 1;
1397 }
1398 if (in_netrange(br->iprange_start, br->ip, br->mask) || in_netrange(br->iprange_end, br->ip, br->mask)) {
1399 fprintf(stderr, "Error: IP range addresses not in network range\n");
1400 return 1;
1401 } 1460 }
1402 } 1461 }
1462
1403 else if (strncmp(argv[i], "--mac=", 6) == 0) { 1463 else if (strncmp(argv[i], "--mac=", 6) == 0) {
1404 Bridge *br = last_bridge_configured(); 1464 if (checkcfg(CFG_NETWORK)) {
1405 if (br == NULL) { 1465 Bridge *br = last_bridge_configured();
1406 fprintf(stderr, "Error: no network device configured\n"); 1466 if (br == NULL) {
1407 return 1; 1467 fprintf(stderr, "Error: no network device configured\n");
1408 } 1468 return 1;
1409 if (mac_not_zero(br->macsandbox)) { 1469 }
1410 fprintf(stderr, "Error: cannot configure the MAC address twice for the same interface\n"); 1470 if (mac_not_zero(br->macsandbox)) {
1411 return 1; 1471 fprintf(stderr, "Error: cannot configure the MAC address twice for the same interface\n");
1472 return 1;
1473 }
1474
1475 // read the address
1476 if (atomac(argv[i] + 6, br->macsandbox)) {
1477 fprintf(stderr, "Error: invalid MAC address\n");
1478 return 1;
1479 }
1412 } 1480 }
1413 1481 else {
1414 // read the address 1482 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n");
1415 if (atomac(argv[i] + 6, br->macsandbox)) { 1483 exit(1);
1416 fprintf(stderr, "Error: invalid MAC address\n");
1417 return 1;
1418 } 1484 }
1419 } 1485 }
1486
1420 else if (strncmp(argv[i], "--mtu=", 6) == 0) { 1487 else if (strncmp(argv[i], "--mtu=", 6) == 0) {
1421 Bridge *br = last_bridge_configured(); 1488 if (checkcfg(CFG_NETWORK)) {
1422 if (br == NULL) { 1489 Bridge *br = last_bridge_configured();
1423 fprintf(stderr, "Error: no network device configured\n"); 1490 if (br == NULL) {
1424 return 1; 1491 fprintf(stderr, "Error: no network device configured\n");
1492 return 1;
1493 }
1494
1495 if (sscanf(argv[i] + 6, "%d", &br->mtu) != 1 || br->mtu < 576 || br->mtu > 9198) {
1496 fprintf(stderr, "Error: invalid mtu value\n");
1497 return 1;
1498 }
1425 } 1499 }
1426 1500 else {
1427 if (sscanf(argv[i] + 6, "%d", &br->mtu) != 1 || br->mtu < 576 || br->mtu > 9198) { 1501 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n");
1428 fprintf(stderr, "Error: invalid mtu value\n"); 1502 exit(1);
1429 return 1;
1430 } 1503 }
1431 } 1504 }
1432 else if (strncmp(argv[i], "--ip=", 5) == 0) {
1433 Bridge *br = last_bridge_configured();
1434 if (br == NULL) {
1435 fprintf(stderr, "Error: no network device configured\n");
1436 return 1;
1437 }
1438 if (br->arg_ip_none || br->ipsandbox) {
1439 fprintf(stderr, "Error: cannot configure the IP address twice for the same interface\n");
1440 return 1;
1441 }
1442 1505
1443 // configure this IP address for the last bridge defined 1506 else if (strncmp(argv[i], "--ip=", 5) == 0) {
1444 if (strcmp(argv[i] + 5, "none") == 0) 1507 if (checkcfg(CFG_NETWORK)) {
1445 br->arg_ip_none = 1; 1508 Bridge *br = last_bridge_configured();
1446 else { 1509 if (br == NULL) {
1447 if (atoip(argv[i] + 5, &br->ipsandbox)) { 1510 fprintf(stderr, "Error: no network device configured\n");
1448 fprintf(stderr, "Error: invalid IP address\n");
1449 return 1; 1511 return 1;
1450 } 1512 }
1513 if (br->arg_ip_none || br->ipsandbox) {
1514 fprintf(stderr, "Error: cannot configure the IP address twice for the same interface\n");
1515 return 1;
1516 }
1517
1518 // configure this IP address for the last bridge defined
1519 if (strcmp(argv[i] + 5, "none") == 0)
1520 br->arg_ip_none = 1;
1521 else {
1522 if (atoip(argv[i] + 5, &br->ipsandbox)) {
1523 fprintf(stderr, "Error: invalid IP address\n");
1524 return 1;
1525 }
1526 }
1451 } 1527 }
1452 } 1528 else {
1453 else if (strncmp(argv[i], "--ip6=", 6) == 0) { 1529 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n");
1454 Bridge *br = last_bridge_configured(); 1530 exit(1);
1455 if (br == NULL) {
1456 fprintf(stderr, "Error: no network device configured\n");
1457 return 1;
1458 }
1459 if (br->arg_ip_none || br->ip6sandbox) {
1460 fprintf(stderr, "Error: cannot configure the IP address twice for the same interface\n");
1461 return 1;
1462 } 1531 }
1532 }
1463 1533
1464 // configure this IP address for the last bridge defined 1534 else if (strncmp(argv[i], "--ip6=", 6) == 0) {
1465 // todo: verify ipv6 syntax 1535 if (checkcfg(CFG_NETWORK)) {
1466 br->ip6sandbox = argv[i] + 6; 1536 Bridge *br = last_bridge_configured();
1537 if (br == NULL) {
1538 fprintf(stderr, "Error: no network device configured\n");
1539 return 1;
1540 }
1541 if (br->arg_ip_none || br->ip6sandbox) {
1542 fprintf(stderr, "Error: cannot configure the IP address twice for the same interface\n");
1543 return 1;
1544 }
1545
1546 // configure this IP address for the last bridge defined
1547 // todo: verify ipv6 syntax
1548 br->ip6sandbox = argv[i] + 6;
1467// if (atoip(argv[i] + 5, &br->ipsandbox)) { 1549// if (atoip(argv[i] + 5, &br->ipsandbox)) {
1468// fprintf(stderr, "Error: invalid IP address\n"); 1550// fprintf(stderr, "Error: invalid IP address\n");
1469// return 1; 1551// return 1;
1470// } 1552// }
1553 }
1554 else {
1555 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n");
1556 exit(1);
1557 }
1471 } 1558 }
1472 1559
1473 1560
1474 else if (strncmp(argv[i], "--defaultgw=", 12) == 0) { 1561 else if (strncmp(argv[i], "--defaultgw=", 12) == 0) {
1475 if (atoip(argv[i] + 12, &cfg.defaultgw)) { 1562 if (checkcfg(CFG_NETWORK)) {
1476 fprintf(stderr, "Error: invalid IP address\n"); 1563 if (atoip(argv[i] + 12, &cfg.defaultgw)) {
1477 return 1; 1564 fprintf(stderr, "Error: invalid IP address\n");
1565 return 1;
1566 }
1567 }
1568 else {
1569 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n");
1570 exit(1);
1478 } 1571 }
1479 } 1572 }
1480#endif 1573#endif
@@ -1496,18 +1589,40 @@ int main(int argc, char **argv) {
1496 return 1; 1589 return 1;
1497 } 1590 }
1498 } 1591 }
1592
1499#ifdef HAVE_NETWORK 1593#ifdef HAVE_NETWORK
1500 else if (strcmp(argv[i], "--netfilter") == 0) 1594 else if (strcmp(argv[i], "--netfilter") == 0) {
1501 arg_netfilter = 1; 1595 if (checkcfg(CFG_NETWORK)) {
1596 arg_netfilter = 1;
1597 }
1598 else {
1599 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n");
1600 exit(1);
1601 }
1602 }
1603
1502 else if (strncmp(argv[i], "--netfilter=", 12) == 0) { 1604 else if (strncmp(argv[i], "--netfilter=", 12) == 0) {
1503 arg_netfilter = 1; 1605 if (checkcfg(CFG_NETWORK)) {
1504 arg_netfilter_file = argv[i] + 12; 1606 arg_netfilter = 1;
1505 check_netfilter_file(arg_netfilter_file); 1607 arg_netfilter_file = argv[i] + 12;
1608 check_netfilter_file(arg_netfilter_file);
1609 }
1610 else {
1611 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n");
1612 exit(1);
1613 }
1506 } 1614 }
1615
1507 else if (strncmp(argv[i], "--netfilter6=", 13) == 0) { 1616 else if (strncmp(argv[i], "--netfilter6=", 13) == 0) {
1508 arg_netfilter6 = 1; 1617 if (checkcfg(CFG_NETWORK)) {
1509 arg_netfilter6_file = argv[i] + 13; 1618 arg_netfilter6 = 1;
1510 check_netfilter_file(arg_netfilter6_file); 1619 arg_netfilter6_file = argv[i] + 13;
1620 check_netfilter_file(arg_netfilter6_file);
1621 }
1622 else {
1623 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n");
1624 exit(1);
1625 }
1511 } 1626 }
1512#endif 1627#endif
1513 //************************************* 1628 //*************************************
@@ -1515,6 +1630,7 @@ int main(int argc, char **argv) {
1515 //************************************* 1630 //*************************************
1516 else if (strcmp(argv[i], "--csh") == 0) { 1631 else if (strcmp(argv[i], "--csh") == 0) {
1517 if (arg_shell_none) { 1632 if (arg_shell_none) {
1633
1518 fprintf(stderr, "Error: --shell=none was already specified.\n"); 1634 fprintf(stderr, "Error: --shell=none was already specified.\n");
1519 return 1; 1635 return 1;
1520 } 1636 }
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index 723889dd2..038676635 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -179,37 +179,51 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
179 } 179 }
180 else if (strcmp(ptr, "netfilter") == 0) { 180 else if (strcmp(ptr, "netfilter") == 0) {
181#ifdef HAVE_NETWORK 181#ifdef HAVE_NETWORK
182 arg_netfilter = 1; 182 if (checkcfg(CFG_NETWORK))
183 arg_netfilter = 1;
184 else
185 fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n");
183#endif 186#endif
184 return 0; 187 return 0;
185 } 188 }
186 else if (strncmp(ptr, "netfilter ", 10) == 0) { 189 else if (strncmp(ptr, "netfilter ", 10) == 0) {
187#ifdef HAVE_NETWORK 190#ifdef HAVE_NETWORK
188 arg_netfilter = 1; 191 if (checkcfg(CFG_NETWORK)) {
189 arg_netfilter_file = strdup(ptr + 10); 192 arg_netfilter_file = strdup(ptr + 10);
190 if (!arg_netfilter_file) 193 if (!arg_netfilter_file)
191 errExit("strdup"); 194 errExit("strdup");
192 check_netfilter_file(arg_netfilter_file); 195 check_netfilter_file(arg_netfilter_file);
196 }
197 else
198 fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n");
193#endif 199#endif
194 return 0; 200 return 0;
195 } 201 }
196 else if (strncmp(ptr, "netfilter6 ", 11) == 0) { 202 else if (strncmp(ptr, "netfilter6 ", 11) == 0) {
197#ifdef HAVE_NETWORK 203#ifdef HAVE_NETWORK
198 arg_netfilter6 = 1; 204 if (checkcfg(CFG_NETWORK)) {
199 arg_netfilter6_file = strdup(ptr + 11); 205 arg_netfilter6 = 1;
200 if (!arg_netfilter6_file) 206 arg_netfilter6_file = strdup(ptr + 11);
201 errExit("strdup"); 207 if (!arg_netfilter6_file)
202 check_netfilter_file(arg_netfilter6_file); 208 errExit("strdup");
209 check_netfilter_file(arg_netfilter6_file);
210 }
211 else
212 fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n");
203#endif 213#endif
204 return 0; 214 return 0;
205 } 215 }
206 else if (strcmp(ptr, "net none") == 0) { 216 else if (strcmp(ptr, "net none") == 0) {
207#ifdef HAVE_NETWORK 217#ifdef HAVE_NETWORK
208 arg_nonetwork = 1; 218 if (checkcfg(CFG_NETWORK)) {
209 cfg.bridge0.configured = 0; 219 arg_nonetwork = 1;
210 cfg.bridge1.configured = 0; 220 cfg.bridge0.configured = 0;
211 cfg.bridge2.configured = 0; 221 cfg.bridge1.configured = 0;
212 cfg.bridge3.configured = 0; 222 cfg.bridge2.configured = 0;
223 cfg.bridge3.configured = 0;
224 }
225 else
226 fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n");
213#endif 227#endif
214 return 0; 228 return 0;
215 } 229 }