LỚP SECURITYMANAGER VÀ PERMISSION

Như ở trên đã nêu, một lớp được nạp vào JVM bằng một bộ nạp lớp và được kiểm định bởi bộ kiểm tra. Cơ chế đảm bảo an ninh thứ ba trong môi trường Java được thực hiện bời bộ quản lý bào mật thông qua lớp SecurityManager. Nó kiểm tra xem những thao tác chi định có được phép hay không. Những thao tác cần kiểm tra tính an ninh bao gồm:

  • Luồng hiện thời có thể tạo ra một bộ nạp lóp mới;
  • Luồng hiện thời có thể tạo ra một tiến trình con;
  • Luồng hiện thời có thể dừng JVM;
  • Luồng hiện thời có thể truy cập vào các thành phần của lớp khác,
  • Luồng hiện thời có thề truy cập hoặc làm thay đổi các thuộc tính cùa hệ thống;
  • Luồng hiện thời có thể đpc hoặc ghi vào một tệp;
  • Luồng hiện thời có thể xoá một tệp;
  • Luồng hiện thời có thề kết nổi với một Socket từ một máy xác định thông qua số hiệu của cổng;
  • Luồng hiện thời có thể phải chờ, hay mờ kết nối với một Socket từ một máy xác định thông qua số hiệu của cống,
  • Luồng hiện ửkri có thề gọi các phuong thức: stop ( ) , suspendo , resumí), setPriorìty{) , setName ( ) , setDaemon ( ) của một luồng hoặc của một nhóm luồng;
  • Luồng hiện thời có thể bắt đầu in một tệp,
  • Luồng hiện thời có thề truy cập vào vùng nhớ giành riêng của hệ thống;
  • v.v

Khi chạy chương trình ứng dụng Java, mặc định nó được thực hiện không có quản lý an ninh. Muốn cài đặt nó trong chương trinh ứng dụng phải gọi phương thức setcurityManager() cùa lóp System.

1. Vấn để bảo mật trong Java 2 Platform

Các JDK 1.0, 1.1 có mô hình bảo mật khá đơn giản: các đối tượng trong chương trình ứng dung độc lập có toàn quyền truy cập tới các tài nguyên cục bộ, còn bộ quàn lý an ninh cùa các applet từ chối mọi truy cập tới các tài nguyên cục bộ.

Java 2 Platform có cơ chế quản lý an ninh linh hoạt hơn. Nó sử dụng một chinh sách hào mật để cấp quyền (giấp phép) được phép thực hiện cho từng chương trình khác nhau.

Trong.đó, quyền là một đặc tính được phép thực hiện và được kiểm soát bời bộ quản lý an ninh, còn được gọi là đặc quyền. JDK1.2 hỗ trợ tạo ra những lóp dể tạo ra các quyền cho chương trinh.

Ví dụ

FilePermission p == new FilePermission(“/tmp/*”, “read, write”); cho phép đọc, ghi một tệp bất kỳ ở thư mục / tmp.

Các lớp quản lý quyền thao tác trong JDK 1.2 tạo ra một cấu trúc phân cấp như hình 7.3. JDK cung cấp mô hình chuẩn đề kiểm tra quyền thao tác dựa trên hai lớp: java.security.SecurityClassLoader java.lang.SecurityManager

Ngoài ra, mô hình chuẩn còn dựa vào đối tượng của lớp Policy để cấp quyền thao tác cho các chương trình nguồn. Tại mỗi thời điểm chi có một đối tượng cùa Policy được quyền vận dụng. Ta có thể sử dụng

Policy curentPolicy = Policy.getPolicy0 để xác định chính sách hiện thời được phép thực hiện của chương trình?

Chi tiết hơn về vấn đề báo mật với Java, nhất là mô hình bảo mật cơ sở của Java ứng dụng trong việc phát triển những hệ thống nhúng, thẻ thông minh, V.V., bạn có thể đọc ở tài liệu trực tuyến http://www.securingiava.com.

java. lang. SecuntyManager                                                                                   

  • void checkPermission(Permission p)
  • void checkPermission(Permission p, object context)

Kiểm tra xem chính sách báo mật hiện thời có cho phép hay không.

java lang. SccuntyManager                                                                             

  • static Polio/ getPolicỵO ‘• Xác định chính sách hiện thời.
  • PermissionCollection getPermissions(CodeSource source) Lấy lại quyền được thao tác đối với source cho trước.

java. lang. PermissionCollectíon   

  • void add(Fermission p); Bổ sung thêm quyền p vào tuyển tập các quyền cấp trước.
  • Enumeration elements (): Lấy ra dãy liệt kê các quyền trong tuyển tập.

java.lang.CođeSource 

  • Certificate [ ] geteCertificate(): Xác định các chứng chỉ đối với tệp lớp ứng với nguồn gốc của chương trinh.
  • URL getLocation (): Xác định vị trí (địa chỉ) của các tệp lớp ứng với nguồn gốc của chương trình.
  • Các tệp chính sách bảo mật

Như ở trên đã nêu, SecurityClassLoader thực hiện việc trao quyền thao tác cho các lớp được nạp vào JVM thông qua các đối tượng của lớp Policy. Ngoầi ra ta còn có thể cài đặt một lớp Policy riêng để cấp quyền cho chương trình. Ở chương V ta cũng đã sữ dụng tệp chính sách (.policy) để có được quyền truy cập từ xa vào các máy tính trên mạng. Ví dụ, một tệp MyApp.policy mẫu có dạng

grant CodeBase WWW,horstmann.com/classes{

permission java.io.FilePermission “/trip/*”, “read,write”;

};

cấp quyền đọc, ghi các tệp vào thư mục /tmp cho tất cả các mã được nạp từ www.horstmann.coni/classes. Ta có thể sử dụng bất kỳ hệ soạn thảo nào, như Notepad, Office Word, Jcreator, V. V, để soạn thảo các tệp chính sách (dưới dạng tệp văn bản).

Lưu ý:

  1. Lớp chính sách mặc định được đặt trong tệp security ờ thư mục con /jre/ịib của JDK Theo mặc định, tệp này chứa dòng

policy.provider=sun.security.provider.policyFile

  1. Ta có thể thay đổi các vị trí cùa các tệp chính sách trong security. Tệp chính sách của java: java.policy được đặc tà mặc định là:

policy.url.l=file:${java.home}/lib/security/j ava.policy policy.url.2=file:${user.home}/java.policy        .

Người quản trị hệ thống có thể thay đổi tệp java.policy và chì rõ những địa chỉ URL thường trực trên những Server khác.

Thực hiện MyApp với quyền được cấp trong tệp MỵApp.policy nêu trên như sau: java -Djava.security.policy = MyApp.policy MyApp Tương tự đối với Applet, ta thực hiện

appletvlewer -J-Djava.security.policy=MyApplet.policy MyApplet.html

Tệp chính sách chửa một dãy các mục được đảm bảo. Mỗi mục có dạng như sau:

grant codesource ( permission-1 ; permission-2;

} ;

Trong đó,

codesource là cơ sở của mã lệnh CodeBase (có thể không cần khai báo nểu mục đầu vào áp dụng cho tất cả các nguồn) và tên của những người ký giấy chứng nhận (có thể bỏ qua nếu không có yêu cầu về người ký xác nhận).

+ CodeBase xác định nơi chứa các lớp sê được tải về:

CodeBase “url”

  • Nếu URL kết thúc bằng 7’, nghĩa là nó chỉ tới một thư mục, ngược lại là tên của một tệp Ví dụ,

grant CodeBase “www.horstman.com/classes/” {…} grant CodeBase “www.horstman.com/classes/MyApp.jar” {…}

  • CodeBase là một địa chỉ URL và chứa phần tử ngăn cách 7’ giữa các tệp, ngay cả đổi VỚI URL tron^Window, vi dụ

grant CodeBase “f ile : d: users/myapps/classes” {…}

  • Các đậc quyền pe rmì s s ion cỏ dạng cấu trúc như sau:

permission className targetName, actionList

+ className là tên đầy đủ cùa lóp đặc quyền thực hiên, ví dụ nhu

java. net. NetEterrrmissicn, java. net. SocketEfermissicn, java. io. EU.eEtemissi.cn, java.security.SecurityPermission, java.util.PropertyPermission, jaa-aÆ. AWTPermissionjava. security.AllPemission + targetName là tên tệp hay thư mục được đặc quyền thực hiện, có dạng:

Một tệp Một thư mục

Tất cả các tệp cùa thư mục directory

Tất cả các tệp của thư mục hiện thời

Tất cả các tệp của thư mục directory hoặc ở một thư mục con nào đó của nó

Tất cả các tệp của thư mục hiện thời hoặc ở một thư mục con nào đó của nó

Tất cả các tệp trong hệ thống.

+ actionList là danh sách các hành động như: read, write, delete, execute, accept, connect, listen, resolve.

Ví dụ:

grant CodeBase “file:d:/myapps/classes/”{

permission java. io. FilePermission “Anyapp/-“, “read, write”;

Lưu ý: Một số lớp đặc quyền không cần chi ra targetName và actionList, ví dụ java.security.AllPermission.

3. Bộ quản lý báo mật tùy biến

Trong phần này ta xây dựng bộ quàn lý bảo mậi tuỳ biến đơn giản, đó là lớp ChecksecuritỵManager. Nó kiểm soát việc truy cập vào tệp, đảm bảo rằng những tệp vãn bản (. text) mà nội dung của nó có các từ bị cấm thì không được phép truy cập.

Ta kiểm soát truy cập vào tệp bằng cách viết đè phương thức checkPermission() của lớp SecurityManager.

Ví dụ 7.5. Chương trình kiểm duyệt đọc các nội dung cùa các tệp. Mở một tệp text và đọc nội dung cùa nó. Nếu nội dung của tệp vãn bản không chứa các từ bị cấm thl cho phép truy cập.

// CheckSecurityManager.java

import j ava.security.*; import java.io.*;

public class CheckSecurityManager extends SecurityManager{ private string!] badWords = (“sex”, “drugs”, “C++”};

public void checkPermission(Permission p){ if(p instanceof FilePermission

& & p.getActions() .equals(“read”)) { if(inSameManager()) return;

String fileName = p.getNameO; if(containsBadWords(fileName)) throw

new SecurityException(“Bad words in ” + fileName);

}

else super.checkPermission(p);

}

boolean inSameManager(){

Class [] cc = getClassContext();

// BỎ qua tập các lời gọi tới bộ quàn lý

int i = 0;

while(i < cc.length && cc[0] == cc[í]) i++;

// Kiểm tra xem có lời gọi khác tới bộ quản lý không

whíle(i < cc.length){

if(cc[0] == cc[í]) return true;

Í++;

}

return false;

}

boolean containsBadWords(String fileName){

if (!fileName.toLowerCase().endsWith(“text”)) return false;

// Chỉ kiểm tra tệp .text

BufferedReader in = null;

try {

in = new BufferedReaderinew FileReader(fileName)); String s;

while((s = in. readLine () )                != nul’l){

for(int i = 0; i < badWords.length; i++) if(s.toLowerCase().indexOf(badWords[i]) != -1) return true;

1

in.close(); return false;

}catch(IOException e) {
return true;

}finally!

if(in != null) try{in.close();

}catch(IOException e){

}

}

}

}

// SecurityManagerTest.] ava

import j ava.awt.*; import j ava.awt.event.*; import java.io.*; import j ava.util.*; import j ava.net.*; import j avax.swing.*;

public class SecurityManagerTest{

public static void main (String args [ ]){

System.setSecurityManager(new CheckSecurityManager() ) ; JFrame frame = new SecurityManagerTestFrame(); frame.show();

)

}

class SecurityManagerTestFrame extends JFrame{ private JTextField fileNameField; private JTextArea fileText; public SecurityManagerTestFrame(){

setTitie(“Security Manager Test”); setSize(400, 300);

addWindowListener(new WindowAdapter(){

public void windowclosing (WindowEvent e)( System.exit(0);

}

fileNameField = new JTextField (20);

JPanel panel = new JPanel();

panel . add (new JLabelC’Text File: “));

panel.add(fileNameField);

JRutton openButton = new JButton(“Open”); panel.add(openButton);

openButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ loadFile{fileNameField.getText());

}

}) ;

Container contentPane = getContentPane ( ); contentPane.add(panel, “North”); flle’l’ext = new JTextArea();

eontentPane.add (new JScro 11Pane (fileText), “Center”) ;

}

public void loadFile(String fileName){ try{

filcText.setText(“”);

BufferedReader i n =

new BufferedReader(new FileReader(fileName)); String s;

while ( ( s = in.readLine() ) != null)

fileText.append(s + “\n”); in.close();

}catch(IOException e)(

fileText.append(“I am sorry, I cant do that.”);

}

}

}

Để tách tệp CheckSecurityManager. class ra khỏi các tệp lớp khác, ta có thể tạo ra một tệp . j a r để lưu giữ tệp đó.

jar cvf FileCheck.jar CheckSecurityManager.class

Lệnh này đồng thời xóa CheckSecurityManager. class khôi thư mục hiện thời.

Tượng tự như ví dụ trước, để chạy được chương trinh trên thì phải tạo ra tệp chính sách, tệp CheckSecurity.policy dạng:

grant CodeBase “file:FileCheck.jar”{ permission java.security.Allpermission;

};

Chính sách này đảm bảo các lớp trong FileCheck .jar được thực hiện hầu như tất cả mọi đặc quyền.

Sau cùng, ta thực hiện chương trình nêu trên như sau: java -Djava. security.policy= CheckSecurity.policy

-classpath FileCheck.jar;. CheckSecurityManager.java

java. lang. SecurityManager

  • Class[] getClassContext()

Trả lại một mảng các lóp cho các phương thức đang thực hiện.

  • void checkCreateClassLoader()

Kiểm tra xem luồng hiện thời có tạo ra một bộ nạp lớp hay không.

  • void checkAccess(Thread g)

Kiểm fra xem luồng hiện thời có thể gọi các phương thức stop (), suspend (), resume (), setNawe (), setDaemon () của luồng g.

  • void checkExit(int status)

Kiểm tra xem luồng hiện thời có thể thoát khỏi JVM với trạng thái status.

  • void checkExec(String cmd)

Kiểm tra xem luồng hiện thôi có thể thoát khỏi JVM với trạng thái status.

  • void checkRead(FileDescriptor fd)
  • void checkRead(String file)
  • void checkWrite(FileDescriptor fd)
  • void checkWrite(String file)
  • void checkDelete(String file)

Kiểm tra xem luồng hiện thời có thể đọc, ghi, xoâ tệp.