In progress of refining the Tomoyo policies for process jailing; will define a set...
[iot2.git] / iotjava / iotruntime / master / ProcessJailConfig.java
1 package iotruntime.master;
2
3 import java.io.InputStream;
4 import java.io.InputStreamReader;
5 import java.io.BufferedReader;
6 import java.io.BufferedWriter;
7 import java.io.FileWriter;
8 import java.io.PrintWriter;
9 import java.io.IOException;
10 import java.nio.file.Files;
11 import java.nio.file.Paths;
12 import java.nio.charset.StandardCharsets;
13 import java.util.HashMap;
14 import java.util.Map;
15
16 /** Class ProcessJailConfig is a class that configures the compute
17  *  nodes in our network with the relevant process jail policies;
18  *  <p>
19  *  We use Tomoyo 2.5 as a Mandatory Access Control (MAC) that is
20  *  simple, easy to maintain, and lightweight (suitable for embedded
21  *  devices).
22  *
23  * @author      Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
24  * @version     2.0
25  * @since       2017-04-07
26  */
27 public final class ProcessJailConfig {
28
29         /**
30          * ProcessJailConfig constants
31          */
32         private static final String STR_SSH_USERNAME_ROUTER = "root";
33         private static final String STR_SSH_USERNAME_HOST   = "iotuser";
34         private static final String STR_TCP_PROTOCOL = "tcp";
35         private static final String STR_UDP_PROTOCOL = "udp";
36         private static final String STR_TCPGW_PROTOCOL = "tcpgw";
37         private static final String STR_NO_PROTOCOL = "nopro";
38
39         private static final String STR_MAC_POLICY_EXT          = ".tomoyo.pol";
40         private static final String STR_OBJECT_NAME             = "<object-name>";
41         private static final String STR_MASTER_IP_ADDRESS       = "<master-ip-address>";
42         private static final String STR_MASTER_COM_PORT         = "<master-com-port>";
43         private static final String STR_RMI_REG_PORT            = "<rmi-reg-port>";
44         private static final String STR_RMI_STUB_PORT           = "<rmi-stub-port>";
45         private static final String STR_DEV_IP_ADDRESS          = "<dev-ip-address>";
46         private static final String STR_DEV_COM_PORT            = "<dev-com-port>";
47         private static final String STR_DEV_PORT                        = "<dev-port>";
48
49
50         /**
51          * ProcessJailConfig properties
52          */
53         private Map<String, PrintWriter> mapHostToFile;
54         private Map<String, String> mapMACtoIPAdd;
55
56
57         /**
58          * Constructor
59          */
60         public ProcessJailConfig() {
61                 // This maps hostname to file PrintWriter
62                 mapHostToFile = new HashMap<String, PrintWriter>();
63                 mapMACtoIPAdd = null;
64         }
65
66
67         /**
68          * renewPrintWriter() renews the mapHostToFile object that lists all PrintWriters
69          *
70          * @return  void
71          */
72         public void renewPrintWriter() {
73
74                 mapHostToFile = new HashMap<String, PrintWriter>();
75         }
76
77
78         /**
79          * getPrintWriter() gets the right PrintWriter object to print policies to the right file
80          *
81          * @param   strConfigHost String hostname to be configured
82          * @return  PrintWriter
83          */
84         private PrintWriter getPrintWriter(String strConfigHost) {
85
86                 // Return object if existing
87                 if (mapHostToFile.containsKey(strConfigHost)) {
88                         return mapHostToFile.get(strConfigHost);
89                 } else {
90                 // Simply create a new one if it doesn't exist
91                         FileWriter fw = null;
92                         try {
93                                 fw = new FileWriter(strConfigHost + STR_MAC_POLICY_EXT);
94                         } catch (IOException ex) {
95                                 ex.printStackTrace();
96                         }
97                         PrintWriter pwConfig = new PrintWriter(new BufferedWriter(fw));
98                         mapHostToFile.put(strConfigHost, pwConfig);
99                         return pwConfig;
100                 }
101         }
102         
103
104         /**
105          * close() closes all PrintWriter objects
106          *
107          * @return  void
108          */
109         public void close() {
110
111                 for(PrintWriter pwConfig: mapHostToFile.values()) {
112                         pwConfig.close();
113                 }
114         }
115
116
117         /**
118          * sendMACPolicies() deploys policies on MAC implementation for process jailing
119          *
120          * @param   strConfigHost String hostname to be configured
121          * @return  void
122          */
123         public void sendMACPolicies(String strConfigHost) {
124
125                 String strCmdSend = "scp " + strConfigHost + STR_MAC_POLICY_EXT + " " + 
126                         STR_SSH_USERNAME_HOST + "@" + strConfigHost + ":~;";
127                 System.out.println(strCmdSend);
128                 runCommand(strCmdSend);
129                 String strCmdDeploy = "ssh " + STR_SSH_USERNAME_HOST + "@" + strConfigHost +
130                         " sudo tomoyo-loadpolicy -df < ~/" + strConfigHost + STR_MAC_POLICY_EXT + "; rm ~/" + strConfigHost + 
131                         STR_MAC_POLICY_EXT + ";";
132                 System.out.println(strCmdDeploy);
133                 runCommand(strCmdDeploy);
134         }
135
136
137         /**
138          * deployPolicies() method configures the policies
139          *
140          * @param   strCommand  String that contains command line
141          * @return  void
142          */
143         private void deployPolicies(String strCommand) {
144
145                 try {
146                         Runtime runtime = Runtime.getRuntime();
147                         Process process = runtime.exec(strCommand);
148                         process.waitFor();
149                 } catch (IOException ex) {
150                         System.out.println("RouterConfig: IOException: " + ex.getMessage());
151                         ex.printStackTrace();
152                 } catch (InterruptedException ex) {
153                         System.out.println("RouterConfig: InterruptException: " + ex.getMessage());
154                         ex.printStackTrace();
155                 }
156         }
157
158
159         /**
160          * setAddressListObject() method sets the map for IP and MAC addresses
161          * <p>
162          * This method gets the mapping from RouterConfig
163          */
164         public void setAddressListObject(Map<String, String> _mapMACtoIPAdd) {
165
166                 mapMACtoIPAdd = _mapMACtoIPAdd;
167         }
168
169
170         /**
171          * runCommand() method runs shell command
172          *
173          * @param   strCommand  String that contains command line
174          * @return  void
175          */
176         private void runCommand(String strCommand) {
177
178                 try {
179                         Runtime runtime = Runtime.getRuntime();
180                         Process process = runtime.exec(strCommand);
181                         process.waitFor();
182                 } catch (IOException ex) {
183                         System.out.println("RouterConfig: IOException: " + ex.getMessage());
184                         ex.printStackTrace();
185                 } catch (InterruptedException ex) {
186                         System.out.println("RouterConfig: InterruptException: " + ex.getMessage());
187                         ex.printStackTrace();
188                 }
189         }
190
191
192         /**
193          * getAddressList() method gets list of IP addresses
194          * <p>
195          * This method sends an inquiry to the router to look for
196          * the list of DHCP leased addresses and their mapping to MAC
197          * addresses
198          *
199          * @param  strRouterAddress  String that contains address of router
200          */
201         public void getAddressList(String strRouterAddress) {
202
203                 //HashMap<String,String> hmMACToIPAdd = new HashMap<String,String>();
204                 try {
205                         // We can replace "cat /tmp/dhcp.leases" with "cat /proc/net/arp"
206                         String cmd = "ssh " + STR_SSH_USERNAME_ROUTER + "@" + strRouterAddress +
207                          " cat /tmp/dhcp.leases";
208                         Runtime runtime = Runtime.getRuntime();
209                         Process process = runtime.exec(cmd);
210
211                         InputStream inStream = process.getInputStream();
212                         InputStreamReader isReader = new InputStreamReader(inStream);
213                         BufferedReader bReader = new BufferedReader(isReader);
214                         String strRead = null;
215                         while((strRead = bReader.readLine()) != null){
216                                 String[] str = strRead.split(" ");
217                                 mapMACtoIPAdd.put(str[1], str[2]);
218                         }
219                 } catch (IOException ex) {
220                         System.out.println("RouterConfig: IOException: " + ex.getMessage());
221                         ex.printStackTrace();
222                 }
223         }
224
225
226         /**
227          * getIPFromMACAddress() method gets IP from MAC address
228          *
229          * @return  String  String that contains IP address from the MAC-IP mapping
230          */      
231         public String getIPFromMACAddress(String strMACAddress) {
232
233                 String strIPAddress = mapMACtoIPAdd.get(strMACAddress);
234                 if (strIPAddress == null) {
235                         throw new Error("RouterConfig: MAC address " + strMACAddress + 
236                                 " not found on the list! Please check if device is present in /tmp/dhcp.leases!");
237                 }
238                 return strIPAddress;
239         }
240
241
242         /**
243          * readFile() read the entire file and return a string
244          *
245          * @return  String  String that contains the content of the file
246          */      
247         public String readFile(String filePath) {
248
249                 String retStr = null;
250                 try {
251                         retStr = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8);
252                 } catch (IOException ex) {
253                         ex.printStackTrace();
254                 }
255                 return retStr;
256         }
257
258
259         /**
260          * configureProcessJailDeviceDriverPolicies() method configures the main MAC policies
261          * <p>
262          * This method configures the main policies between controller and device driver
263          *
264          * @param   strConfigHost                       String hostname to be configured
265          * @param   strObjectName                       String object name
266          * @param   strFileName                         String policy file path and name
267          * @param   strMasterIPAddress          String master IP address
268          * @param   iComPort                            Integer communication port (controller-driver)
269          * @param   iRMIRegPort                         Integer RMI registry port
270          * @param   iRMIStubPort                        Integer RMI stub port
271          * @return  void
272          */
273         public void configureProcessJailDeviceDriverPolicies(String strConfigHost, String strObjectName, 
274                         String strFileName, String strMasterIPAddress, int iComPort, int iRMIRegPort, int iRMIStubPort) {
275
276                 PrintWriter pwConfig = getPrintWriter(strConfigHost);
277                 String strPolicyList = readFile(strFileName);
278                 // Replace the strings with the actual values
279                 String strNewPolicyList = strPolicyList.replace(STR_OBJECT_NAME, strObjectName).replace(STR_MASTER_IP_ADDRESS,
280                         strMasterIPAddress).replace(STR_MASTER_COM_PORT, String.valueOf(iComPort)).replace(STR_RMI_REG_PORT,
281                         String.valueOf(iRMIRegPort)).replace(STR_RMI_STUB_PORT, String.valueOf(iRMIStubPort));
282                 pwConfig.println("\n");
283                 pwConfig.print(strNewPolicyList);
284         }
285
286
287         /**
288          * configureProcessJailDevicePolicies() method configures the device MAC policies
289          * <p>
290          * This method configures the device policies between device driver and device
291          *
292          * @param   strConfigHost                       String hostname to be configured
293          * @param   strProtocol                         String protocol name
294          * @param       iDeviceComPort                  Integer device communication port
295          * @param   strDeviceIPAddress          String device IP address
296          * @param   iDevicePort                         Integer device port
297          * @return  void
298          */
299         public void configureProcessJailDevicePolicies(String strConfigHost, String strProtocol,
300                         int iDeviceComPort, String strDeviceIPAddress, int iDevicePort) {
301
302                 PrintWriter pwConfig = getPrintWriter(strConfigHost);
303                 if (strProtocol.equals(STR_TCP_PROTOCOL)) {
304                         pwConfig.println("network inet stream connect ::ffff:" + strDeviceIPAddress + " " + String.valueOf(iDevicePort));
305                 } else {
306                         pwConfig.println("network inet dgram bind :: " + String.valueOf(iDeviceComPort));
307                         pwConfig.println("network inet dgram send ::ffff:" + strDeviceIPAddress + " " + String.valueOf(iDevicePort));
308                 }
309         }
310
311
312         /**
313          * configureProcessJailControllerPolicies() method configures the main MAC policies for controller
314          *
315          * @param   strControllerName           String controller name to be configured
316          * @param   strFileName                         String policy file path and name
317          * @param   strMasterIPAddress          String master IP address
318          * @param   iComPort                            Integer communication port (controller-driver)
319          * @return  void
320          */
321         public void configureProcessJailControllerPolicies(String strControllerName, String strFileName, 
322                         String strMasterIPAddress, int iComPort) {
323
324                 PrintWriter pwConfig = getPrintWriter(strControllerName);
325                 String strPolicyList = readFile(strFileName);
326                 // Replace the strings with the actual values
327                 String strNewPolicyList = strPolicyList.replace(STR_MASTER_IP_ADDRESS,
328                         strMasterIPAddress).replace(STR_MASTER_COM_PORT, String.valueOf(iComPort));
329                 pwConfig.println("\n");
330                 pwConfig.print(strNewPolicyList);
331         }
332
333
334         /**
335          * configureProcessJailContRMIPolicies() method configures the MAC policies for RMI ports of controller
336          *
337          * @param   strControllerName           String controller name to be configured
338          * @param   strFileName                         String policy file path and name
339          * @param   strMasterIPAddress          String master IP address
340          * @param   iComPort                            Integer communication port (controller-driver)
341          * @return  void
342          */
343         public void configureProcessJailContRMIPolicies(String strControllerName, String strDeviceDriverIPAddress, 
344                         int iRMIRegPort, int iRMIStubPort) {
345
346                 PrintWriter pwConfig = getPrintWriter(strControllerName);
347                 // Replace the strings with the actual values
348                 pwConfig.println("network inet stream connect ::ffff:" + strDeviceDriverIPAddress + " " + String.valueOf(iRMIRegPort));
349                 pwConfig.println("network inet stream connect ::ffff:" + strDeviceDriverIPAddress + " " + String.valueOf(iRMIStubPort));
350         }
351
352
353         /**
354          * combineControllerMACPolicies() method combines the controller MAC policies into the right host policy file
355          *
356          * @param   strConfigHost                       String hostname to be configured
357          * @param   strFileName                         String policy file path and name
358          * @return  void
359          */
360         public void combineControllerMACPolicies(String strConfigHost, String strObjectControllerName, String strFileName) {
361
362                 PrintWriter pwConfig = getPrintWriter(strConfigHost);
363                 PrintWriter pwCont = getPrintWriter(strObjectControllerName);
364                 pwCont.close();
365                 String strPolicyList = readFile(strFileName);
366                 pwConfig.println(strPolicyList);
367                 runCommand("rm -rf " + strFileName);
368         }
369 }
370
371