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