more info in doc
[feisty_meow.git] / nucleus / library / security / windows_firewall.cpp
1 /*****************************************************************************\
2 *                                                                             *
3 *  Name   : windows firewall wrapper                                          *
4 *  Author : Chris Koeritz                                                     *
5 *                                                                             *
6 *******************************************************************************
7 * Copyright (c) 2009-$now By Author.  This program is free software; you can  *
8 * redistribute it and/or modify it under the terms of the GNU General Public  *
9 * License as published by the Free Software Foundation; either version 2 of   *
10 * the License or (at your option) any later version.  This is online at:      *
11 *     http://www.fsf.org/copyleft/gpl.html                                    *
12 * Please send any updates to: fred@gruntose.com                               *
13 \*****************************************************************************/
14
15 #include "windows_firewall.h"
16
17
18 #include <basis/functions.h>
19
20 using namespace portable;
21
22 // so far this is a good assumption about where to find netsh.
23 astring netsh_app() { return env_string("WINDIR") + "/System32/netsh.exe"; }
24
25 int windows_firewall::poke_firewall_hole(const astring &program_name,
26     const astring &exception_name, const astring &hole_description)
27 {
28   astring cmdline;
29 #ifdef __WIN32__
30   known_operating_systems kind = determine_OS();
31   if ( (kind == WIN_SRV2K8) || (kind == WIN_VISTA) ) {
32     // newer style firewall with advfirewall.
33 //::MessageBox(0, "poke app srv2k8", "yodel", MB_OK);
34     cmdline = a_sprintf("-c advfirewall firewall add rule name=\"%s\" dir=in "
35         "action=allow program=\"%s\" enable=yes profile=any "
36         "description=\"%s\"", exception_name.s(), program_name.s(),
37         hole_description.s());
38   } else {
39     // older xp style firewall (if that).
40 //::MessageBox(0, "poke app xp", "yodel", MB_OK);
41     cmdline = a_sprintf("-c firewall add allowedprogram program=\"%s\" "
42         "name=\"%s\" mode=enable scope=all profile=all", program_name.s(),
43         exception_name.s());
44   }
45
46   basis::u_int kid_id;
47   basis::u_int to_return = launch_process::run(netsh_app(), cmdline,
48       portable::AWAIT_APP_EXIT | portable::HIDE_APP_WINDOW
49       | portable::SHELL_EXECUTE, kid_id);
50   return to_return;
51 #else
52   if (!program_name || !exception_name || !hole_description) {}  // no problem.
53   return 1;  // failure on this platform.
54 #endif
55 }
56
57 int windows_firewall::remove_firewall_hole(const astring &program_name,
58     const astring &exception_name)
59 {
60 #ifdef __WIN32__
61   astring cmdline;
62
63   known_operating_systems kind = determine_OS();
64   if ( (kind == WIN_SRV2K8) || (kind == WIN_VISTA) ) {
65 //::MessageBox(0, "removing app srv2k8", "yodel", MB_OK);
66     // newer style firewall with advfirewall.
67     cmdline = a_sprintf("-c advfirewall firewall delete rule name=\"%s\" ",
68         exception_name.s());
69   } else {
70 //::MessageBox(0, "removing app xp", "yodel", MB_OK);
71     // older xp style firewall (if that).
72     cmdline = a_sprintf("-c firewall delete allowedprogram program=\"%s\" "
73         "profile=all", program_name.s());
74   }
75
76   basis::u_int kid_id;
77   basis::u_int to_return = launch_process::run(netsh_app(), cmdline,
78       portable::AWAIT_APP_EXIT | portable::HIDE_APP_WINDOW
79       | portable::SHELL_EXECUTE, kid_id);
80   return to_return;
81 #else
82   if (!program_name || !exception_name) {}  // no problem.
83   return 1;  // failure on this platform.
84 #endif
85 }
86
87 int windows_firewall::poke_firewall_hole(int port_number,
88     const astring &exception_name, const astring &hole_description,
89     const astring &protocol)
90 {
91 #ifdef __WIN32__
92   astring cmdline;
93
94   known_operating_systems kind = determine_OS();
95   if ( (kind == WIN_SRV2K8) || (kind == WIN_VISTA) ) {
96     // newer style firewall with advfirewall.
97 //::MessageBox(0, "poke port srv2k8", "yodel", MB_OK);
98     cmdline = a_sprintf("-c advfirewall firewall add rule name=\"%s\" dir=in "
99         "action=allow protocol=\"%s\" enable=yes profile=any "
100         "description=\"%s\" localport=%d",
101         exception_name.s(), protocol.s(), hole_description.s(), port_number);
102   } else {
103     // older xp style firewall (if that).
104 //::MessageBox(0, "poke port xp", "yodel", MB_OK);
105     cmdline = a_sprintf("-c firewall add portopening port=%d "
106         "name=\"%s\" protocol=%s mode=enable scope=all profile=all",
107         port_number, exception_name.s(), protocol.s());
108   }
109
110   basis::u_int kid_id;
111   basis::u_int to_return = launch_process::run(netsh_app(), cmdline,
112       portable::AWAIT_APP_EXIT | portable::HIDE_APP_WINDOW
113       | portable::SHELL_EXECUTE, kid_id);
114   return to_return;
115 #else
116   if (!port_number || !exception_name || !protocol || !hole_description) {}  // no problem.
117   return 1;  // failure on this platform.
118 #endif
119 }
120
121 int windows_firewall::remove_firewall_hole(int port_number,
122     const astring &exception_name, const astring &protocol)
123 {
124 #ifdef __WIN32__
125   astring cmdline;
126
127   known_operating_systems kind = determine_OS();
128   if ( (kind == WIN_SRV2K8) || (kind == WIN_VISTA) ) {
129 //::MessageBox(0, "removing port srv2k8", "yodel", MB_OK);
130     // newer style firewall with advfirewall.
131     cmdline = a_sprintf("-c advfirewall firewall delete rule name=\"%s\" "
132         "localport=%d protocol=%s", exception_name.s(),
133         port_number, protocol.s());
134   } else {
135 //::MessageBox(0, "removing port xp", "yodel", MB_OK);
136     // older xp style firewall (if that).
137     cmdline = a_sprintf("-c firewall delete portopening protocol=%s "
138         "port=%d profile=all", protocol.s(), port_number);
139   }
140
141   basis::u_int kid_id;
142   basis::u_int to_return = launch_process::run(netsh_app(), cmdline,
143       portable::AWAIT_APP_EXIT | portable::HIDE_APP_WINDOW
144       | portable::SHELL_EXECUTE, kid_id);
145   return to_return;
146 #else
147   if (!port_number || !exception_name || !protocol) {}  // no problem.
148   return 1;  // failure on this platform.
149 #endif
150 }
151