fba8cad773436bbf2d57f21f3bf0953b46a6367f
[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_ADD_MAC_EXT             = ".tomoyo";
40         private static final String STR_MAC_POLICY_EXT          = ".tomoyo.pol";
41         private static final String STR_OBJECT_NAME             = "<object-name>";
42         private static final String STR_OBJECT_CLASS_NAME       = "<object-class-name>";
43         private static final String STR_MASTER_IP_ADDRESS       = "<master-ip-address>";
44         private static final String STR_MASTER_COM_PORT         = "<master-com-port>";
45         private static final String STR_RMI_REG_PORT            = "<rmi-reg-port>";
46         private static final String STR_RMI_STUB_PORT           = "<rmi-stub-port>";
47         private static final String STR_DEV_IP_ADDRESS          = "<dev-ip-address>";
48         private static final String STR_DEV_COM_PORT            = "<dev-com-port>";
49         private static final String STR_DEV_PORT                        = "<dev-port>";
50         
51     private static final int INT_HTTP_PORT = 80;
52     private static final int INT_DNS_PORT  = 53;
53
54
55         /**
56          * ProcessJailConfig properties
57          */
58         private Map<String, PrintWriter> mapHostToFile;
59         private Map<String, String> mapMACtoIPAdd;
60
61
62         /**
63          * Constructor
64          */
65         public ProcessJailConfig() {
66                 // This maps hostname to file PrintWriter
67                 mapHostToFile = new HashMap<String, PrintWriter>();
68                 mapMACtoIPAdd = null;
69         }
70
71
72         /**
73          * renewPrintWriter() renews the mapHostToFile object that lists all PrintWriters
74          *
75          * @return  void
76          */
77         public void renewPrintWriter() {
78
79                 mapHostToFile = new HashMap<String, PrintWriter>();
80         }
81
82
83         /**
84          * getPrintWriter() gets the right PrintWriter object to print policies to the right file
85          *
86          * @param   strConfigHost String hostname to be configured
87          * @return  PrintWriter
88          */
89         private PrintWriter getPrintWriter(String strConfigHost) {
90
91                 // Return object if existing
92                 if (mapHostToFile.containsKey(strConfigHost)) {
93                         return mapHostToFile.get(strConfigHost);
94                 } else {
95                 // Simply create a new one if it doesn't exist
96                         FileWriter fw = null;
97                         try {
98                                 fw = new FileWriter(strConfigHost + STR_MAC_POLICY_EXT);
99                         } catch (IOException ex) {
100                                 ex.printStackTrace();
101                         }
102                         PrintWriter pwConfig = new PrintWriter(new BufferedWriter(fw));
103                         mapHostToFile.put(strConfigHost, pwConfig);
104                         return pwConfig;
105                 }
106         }
107         
108         
109         /**
110          * flush() flushes all PrintWriter objects
111          *
112          * @return  void
113          */
114         public void flush() {
115
116                 for(PrintWriter pwConfig: mapHostToFile.values()) {
117                         pwConfig.flush();
118                 }
119         }
120         
121
122         /**
123          * close() closes all PrintWriter objects
124          *
125          * @return  void
126          */
127         public void close() {
128
129                 for(PrintWriter pwConfig: mapHostToFile.values()) {
130                         pwConfig.close();
131                 }
132         }
133
134
135         /**
136          * sendMACPolicies() deploys policies on MAC implementation for process jailing
137          *
138          * @param   strConfigHost String hostname to be configured
139          * @return  void
140          */
141         public void sendMACPolicies(String strConfigHost) {
142
143                 String strCmdSend = "scp " + strConfigHost + STR_MAC_POLICY_EXT + " " + 
144                         STR_SSH_USERNAME_HOST + "@" + strConfigHost + ":~;";
145                 System.out.println(strCmdSend);
146                 runCommand(strCmdSend);
147                 String strCmdDeploy = "ssh " + STR_SSH_USERNAME_HOST + "@" + strConfigHost +
148                         " sudo tomoyo-loadpolicy -df < ~/" + strConfigHost + STR_MAC_POLICY_EXT + "; rm ~/" + strConfigHost + 
149                         STR_MAC_POLICY_EXT + ";";
150                 System.out.println(strCmdDeploy);
151                 runCommand(strCmdDeploy);
152         }
153
154
155         /**
156          * deployPolicies() method configures the policies
157          *
158          * @param   strCommand  String that contains command line
159          * @return  void
160          */
161         private void deployPolicies(String strCommand) {
162
163                 try {
164                         Runtime runtime = Runtime.getRuntime();
165                         Process process = runtime.exec(strCommand);
166                         process.waitFor();
167                 } catch (IOException ex) {
168                         System.out.println("RouterConfig: IOException: " + ex.getMessage());
169                         ex.printStackTrace();
170                 } catch (InterruptedException ex) {
171                         System.out.println("RouterConfig: InterruptException: " + ex.getMessage());
172                         ex.printStackTrace();
173                 }
174         }
175
176
177         /**
178          * setAddressListObject() method sets the map for IP and MAC addresses
179          * <p>
180          * This method gets the mapping from RouterConfig
181          */
182         public void setAddressListObject(Map<String, String> _mapMACtoIPAdd) {
183
184                 mapMACtoIPAdd = _mapMACtoIPAdd;
185         }
186
187
188         /**
189          * runCommand() method runs shell command
190          *
191          * @param   strCommand  String that contains command line
192          * @return  void
193          */
194         private void runCommand(String strCommand) {
195
196                 try {
197                         Runtime runtime = Runtime.getRuntime();
198                         Process process = runtime.exec(strCommand);
199                         process.waitFor();
200                 } catch (IOException ex) {
201                         System.out.println("RouterConfig: IOException: " + ex.getMessage());
202                         ex.printStackTrace();
203                 } catch (InterruptedException ex) {
204                         System.out.println("RouterConfig: InterruptException: " + ex.getMessage());
205                         ex.printStackTrace();
206                 }
207         }
208
209
210         /**
211          * getAddressList() method gets list of IP addresses
212          * <p>
213          * This method sends an inquiry to the router to look for
214          * the list of DHCP leased addresses and their mapping to MAC
215          * addresses
216          *
217          * @param  strRouterAddress  String that contains address of router
218          */
219         public void getAddressList(String strRouterAddress) {
220
221                 //HashMap<String,String> hmMACToIPAdd = new HashMap<String,String>();
222                 try {
223                         // We can replace "cat /tmp/dhcp.leases" with "cat /proc/net/arp"
224                         String cmd = "ssh " + STR_SSH_USERNAME_ROUTER + "@" + strRouterAddress +
225                          " cat /tmp/dhcp.leases";
226                         Runtime runtime = Runtime.getRuntime();
227                         Process process = runtime.exec(cmd);
228
229                         InputStream inStream = process.getInputStream();
230                         InputStreamReader isReader = new InputStreamReader(inStream);
231                         BufferedReader bReader = new BufferedReader(isReader);
232                         String strRead = null;
233                         while((strRead = bReader.readLine()) != null){
234                                 String[] str = strRead.split(" ");
235                                 mapMACtoIPAdd.put(str[1], str[2]);
236                         }
237                 } catch (IOException ex) {
238                         System.out.println("RouterConfig: IOException: " + ex.getMessage());
239                         ex.printStackTrace();
240                 }
241         }
242
243
244         /**
245          * getIPFromMACAddress() method gets IP from MAC address
246          *
247          * @return  String  String that contains IP address from the MAC-IP mapping
248          */      
249         public String getIPFromMACAddress(String strMACAddress) {
250
251                 String strIPAddress = mapMACtoIPAdd.get(strMACAddress);
252                 if (strIPAddress == null) {
253                         throw new Error("RouterConfig: MAC address " + strMACAddress + 
254                                 " not found on the list! Please check if device is present in /tmp/dhcp.leases!");
255                 }
256                 return strIPAddress;
257         }
258
259
260         /**
261          * readFile() read the entire file and return a string
262          *
263          * @return  String  String that contains the content of the file
264          */      
265         public String readFile(String filePath) {
266
267                 String retStr = null;
268                 try {
269                         retStr = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8);
270                 } catch (IOException ex) {
271                         ex.printStackTrace();
272                 }
273                 return retStr;
274         }
275
276
277         /**
278          * configureProcessJailDeviceDriverPolicies() method configures the main MAC policies
279          * <p>
280          * This method configures the main policies between controller and device driver
281          *
282          * @param   strConfigHost                       String hostname to be configured
283          * @param   strObjectName                       String object name
284          * @param   strObjectClassName          String object class name
285          * @param   strFileName                         String policy file path and name
286          * @param   strMasterIPAddress          String master IP address
287          * @param   iComPort                            Integer communication port (controller-driver)
288          * @param   iRMIRegPort                         Integer RMI registry port
289          * @param   iRMIStubPort                        Integer RMI stub port
290          * @return  void
291          */
292         public void configureProcessJailDeviceDriverPolicies(String strConfigHost, String strObjectName, String strObjectClassName, 
293                         String strFileName, String strMasterIPAddress, int iComPort, int iRMIRegPort, int iRMIStubPort) {
294
295                 PrintWriter pwConfig = getPrintWriter(strConfigHost);
296                 String strPolicyList = readFile(strFileName);
297                 // Replace the strings with the actual values
298                 String strNewPolicyList = strPolicyList.replace(STR_OBJECT_NAME, strObjectName).
299                         replace(STR_OBJECT_CLASS_NAME, strObjectClassName).
300                         replace(STR_MASTER_IP_ADDRESS, strMasterIPAddress).
301                         replace(STR_MASTER_COM_PORT, String.valueOf(iComPort));
302                         //replace(STR_RMI_REG_PORT, String.valueOf(iRMIRegPort)).
303                         //replace(STR_RMI_STUB_PORT, String.valueOf(iRMIStubPort));
304                 pwConfig.println("\n");
305                 pwConfig.print(strNewPolicyList);
306                 pwConfig.println("network inet stream bind/listen :: " + iRMIRegPort);
307                 pwConfig.println("network inet stream bind/listen :: " + iRMIStubPort);
308         }
309
310
311         /**
312          * configureProcessJailDevicePolicies() method configures the device MAC policies
313          * <p>
314          * This method configures the device policies between device driver and device
315          *
316          * @param   strConfigHost                       String hostname to be configured
317          * @param   strProtocol                         String protocol name
318          * @param       iDeviceComPort                  Integer device communication port
319          * @param   strDeviceIPAddress          String device IP address
320          * @param   iDevicePort                         Integer device port
321          * @return  void
322          */
323         public void configureProcessJailDevicePolicies(String strConfigHost, String strProtocol,
324                         int iDeviceComPort, String strDeviceIPAddress, int iDevicePort) {
325
326                 PrintWriter pwConfig = getPrintWriter(strConfigHost);
327                 if (strProtocol.equals(STR_TCP_PROTOCOL)) {
328                         pwConfig.println("network inet stream connect ::ffff:" + strDeviceIPAddress + " " + String.valueOf(iDevicePort));
329                 } else {
330                         pwConfig.println("network inet dgram bind :: " + String.valueOf(iDeviceComPort));
331                         pwConfig.println("network inet dgram send ::ffff:" + strDeviceIPAddress + " " + String.valueOf(iDevicePort));
332                 }
333         }
334
335
336         /**
337          * configureProcessJailDevicePolicies() method configures the device MAC policies
338          * <p>
339          * This method configures the device policies between device driver and device
340          *
341          * @param   strConfigHost                       String hostname to be configured
342          * @param   strRouterAddress            String router address
343          * @param   iPort                                       Integer port
344          * @return  void
345          */
346         public void configureProcessJailGWDevicePolicies(String strConfigHost, String strRouterAddress, String strDeviceIPAddress, int iPort) {
347
348                 PrintWriter pwConfig = getPrintWriter(strConfigHost);
349                 pwConfig.println("file read /home/iotuser/iot2/iotjava/iotruntime/\\*.jks");
350                 pwConfig.println("file read /etc/resolv.conf");
351                 pwConfig.println("file read /etc/hosts");
352         pwConfig.println("network inet stream connect ::ffff:" + strDeviceIPAddress + " " + String.valueOf(INT_HTTP_PORT));     // HTTP access for this address
353                 pwConfig.println("network inet dgram send " + strRouterAddress + " " + String.valueOf(iPort));
354         }
355
356
357         /**
358          * configureProcessJailDeviceDriverInetAddressPolicies() method configures the device MAC policies
359          * <p>
360          *
361          * @param   strConfigHost       String hostname to be configured
362          * @param   strAddress          String device IP address
363          * @return  void
364          */
365         public void configureProcessJailInetAddressPolicies(String strConfigHost, String strRouterAddress, String strAddress) {
366
367                 PrintWriter pwConfig = getPrintWriter(strConfigHost);
368                 //System.out.println("\n\nDEBUG: Writing the config host address setup!!!\n\n");
369                 pwConfig.println("file read /etc/resolv.conf");
370                 pwConfig.println("file read /etc/hosts");
371                 pwConfig.println("file read /etc/host.conf");
372                 pwConfig.println("network inet dgram send " + strRouterAddress + " " + String.valueOf(INT_DNS_PORT));   // TCP/UDP access through router
373                 pwConfig.println("network inet stream connect ::ffff:" + strAddress + " " + String.valueOf(INT_HTTP_PORT));     // HTTP access for this address
374         }
375
376
377         /**
378          * configureProcessJailControllerPolicies() method configures the main MAC policies for controller
379          *
380          * @param   strControllerName           String controller name to be configured
381          * @param   strFileName                         String policy file path and name
382          * @param   strMasterIPAddress          String master IP address
383          * @param   iComPort                            Integer communication port (controller-driver)
384          * @return  void
385          */
386         public void configureProcessJailControllerPolicies(String strControllerName, String strFileName, 
387                         String strMasterIPAddress, int iComPort) {
388
389                 PrintWriter pwConfig = getPrintWriter(strControllerName);
390                 String strPolicyList = readFile(strFileName);
391                 // Replace the strings with the actual values
392                 String strNewPolicyList = strPolicyList.replace(STR_OBJECT_NAME, strControllerName).
393                         replace(STR_OBJECT_CLASS_NAME, strControllerName).
394                         replace(STR_MASTER_IP_ADDRESS, strMasterIPAddress).
395                         replace(STR_MASTER_COM_PORT, String.valueOf(iComPort));
396                 pwConfig.println("\n");
397                 pwConfig.print(strNewPolicyList);
398         }
399
400
401         /**
402          * configureProcessJailContRMIPolicies() method configures the MAC policies for RMI ports of controller
403          *
404          * @param   strControllerName           String controller name to be configured
405          * @param   strFileName                         String policy file path and name
406          * @param   strMasterIPAddress          String master IP address
407          * @param   iComPort                            Integer communication port (controller-driver)
408          * @return  void
409          */
410         public void configureProcessJailContRMIPolicies(String strControllerName, String strDeviceDriverIPAddress, 
411                         int iRMIRegPort, int iRMIStubPort) {
412
413                 PrintWriter pwConfig = getPrintWriter(strControllerName);
414                 // Replace the strings with the actual values
415                 pwConfig.println("network inet stream connect ::ffff:" + strDeviceDriverIPAddress + " " + String.valueOf(iRMIRegPort));
416                 pwConfig.println("network inet stream connect ::ffff:" + strDeviceDriverIPAddress + " " + String.valueOf(iRMIStubPort));
417         }
418
419
420         /**
421          * combineAdditionalMACPolicy() method combines the additional MAC policies into the right host policy file
422          *
423          * @param   strConfigHost                       String hostname to be configured
424          * @param   strFileName                         String policy file path and name
425          * @return  void
426          */
427         public void combineAdditionalMACPolicy(String strMACCfgPath, String strObjectName, String strConfigHost) {
428
429                 PrintWriter pwConfig = getPrintWriter(strConfigHost);
430                 String strPolicyList = readFile(strMACCfgPath + strObjectName + STR_ADD_MAC_EXT);
431                 pwConfig.println(strPolicyList);
432         }
433
434
435         /**
436          * combineControllerMACPolicies() method combines the controller MAC policies into the right host policy file
437          *
438          * @param   strConfigHost                       String hostname to be configured
439          * @param   strFileName                         String policy file path and name
440          * @return  void
441          */
442         public void combineControllerMACPolicies(String strConfigHost, String strObjectControllerName, String strFileName) {
443
444                 PrintWriter pwConfig = getPrintWriter(strConfigHost);
445                 PrintWriter pwCont = getPrintWriter(strObjectControllerName);
446                 pwCont.close();
447                 String strPolicyList = readFile(strFileName);
448                 pwConfig.println(strPolicyList);
449                 runCommand("rm -rf " + strFileName);
450         }
451 }
452
453