在前文中我们介绍了“Android安全框架”。Android开发包工具将代码和资源数据文件编译成以.apk后缀的安装文件。单个.apk文件就是一个应用程序,可被用来安装在Android系统的手机上。但是你了解Android系统及程序授权机制吗?本文将向我们介绍“Android系统及应用程序授权机制”。

专题详见:http://mobile.51cto.com/hot-282966.htm

 

1.Android系统权限定义

Android系统在/system/core/private/android_filesystem_config.h头文件中对Android用户/用户组作了如下定义,且权限均基于该用户/用户组设置。>Android系统在/system/core/private/android_filesystem_config.h头文件中对Android用户/用户组作了如下定义,且权限均基于该用户/用户组设置。

  1. #define AID_ROOT             0  /* traditional unix root user */ 
  2. #define AID_SYSTEM        1000  /* system server */ 
  3. #define AID_RADIO         1001  /* telephony subsystem, RIL */ 
  4. #define AID_BLUETOOTH     1002  /* bluetooth subsystem */ 
  5. #define AID_GRAPHICS      1003  /* graphics devices */ 
  6. #define AID_INPUT         1004  /* input devices */ 
  7. #define AID_AUDIO         1005  /* audio devices */ 
  8. #define AID_CAMERA        1006  /* camera devices */ 
  9. #define AID_LOG           1007  /* log devices */ 
  10. #define AID_COMPASS       1008  /* compass device */ 
  11. #define AID_MOUNT         1009  /* mountd socket */ 
  12. #define AID_WIFI          1010  /* wifi subsystem */ 
  13. #define AID_ADB           1011  /* android debug bridge (adbd) */ 
  14. #define AID_INSTALL       1012  /* group for installing packages */ 
  15. #define AID_MEDIA         1013  /* mediaserver process */ 
  16. #define AID_DHCP          1014  /* dhcp client */ 
  17. #define AID_SDCARD_RW     1015  /* external storage write access */ 
  18. #define AID_VPN           1016  /* vpn system */ 
  19. #define AID_KEYSTORE      1017  /* keystore subsystem */ 
  20. #define AID_USB           1018  /* USB devices */ 
  21. #define AID_DRM           1019  /* DRM server */ 
  22. #define AID_DRMIO         1020  /* DRM IO server */ 
  23. #define AID_GPS           1021  /* GPS daemon */ 
  24. #define AID_NFC           1022  /* nfc subsystem */ 
  25.  
  26. #define AID_SHELL         2000  /* adb and debug shell user */ 
  27. #define AID_CACHE         2001  /* cache access */ 
  28. #define AID_DIAG          2002  /* access to diagnostic resources */ 
  29.  
  30. /* The 3000 series are intended for use as supplemental group id's only. 
  31.  * They indicate special Android capabilities that the kernel is aware of. */ 
  32. #define AID_NET_BT_ADMIN  3001  /* bluetooth: create any socket */ 
  33. #define AID_NET_BT        3002  /* bluetooth: create sco, rfcomm or l2cap sockets */ 
  34. #define AID_INET          3003  /* can create AF_INET and AF_INET6 sockets */ 
  35. #define AID_NET_RAW       3004  /* can create raw INET sockets */ 
  36. #define AID_NET_ADMIN     3005  /* can configure interfaces and routing tables. */ 
  37.  
  38. #define AID_MISC          9998  /* access to misc storage */ 
  39. #define AID_NOBODY        9999 
  40.  
  41. #define AID_APP          10000 /* first app user */ 

值得注意的是:每个应用程序在安装到Android系统后,系统都会为其分配一个用户ID,如app_4、app_11等。以下是Calendar和Terminal软件在Android系统中进程浏览的结果(其中,黑色字体标明的即为应用分配的用户ID):

 

Android系统中进程浏览的结果
USER PID PPID VSIZE RSS WCHAN PC NAME
app_16 2855 2363 216196 20960 ffffffff afd0ee48 S com.android.providers.calendar
app_91 4178 2363 218872 25076 ffffffff afd0ee48 S jackpal.androidterm

 

在Android系统中,上述用户/用户组对文件的访问遵循Linux系统的访问控制原则,即根据长度为10个字符的权限控制符来决定用户/用户组对文件的访问权限。该控制符的格式遵循下列规则:

(1) 第1个字符:表示一种特殊的文件类型。其中字符可为d(表示该文件是一个目录)、b(表示该文件是一个系统设备,使用块输入/输出与外界交互,通常为一个磁盘)、c(表示该文件是一个系统设备,使用连续的字符输入/输出与外界交互,如串口和声音设备),“.”表示该文件是一个普通文件,没有特殊属性。

(2) 2~4个字符:用来确定文件的用户(user)权限;

(3) 5~7个字符:用来确定文件的组(group)权限;

(4) 8~10个字符:用来确定文件的其它用户(other user,既不是文件所有者,也不是组成员的用户)的权限。

(5) 第2、5、8个字符是用来控制文件的读权限的,该位字符为r表示允许用户、组成员或其它人可从该文件中读取数据。短线“-”则表示不允许该成员读取数据。

(6) 第3、6、9位的字符控制文件的写权限,该位若为w表示允许写,若为“-”表示不允许写。

(7) 第4、7、10位的字符用来控制文件的制造权限,该位若为x表示允许执行,若为“-”表示不允许执行。

举个例子,“drwxrwxr--  2 root   root    4096  2月 11 10:36 guo”表示的访问控制权限(黑色字体标明)为:因为guo的第1个位置的字符是d,所以由此知道guo是一个目录。第2至4位置上的属性是rwx,表示用户root拥有权限列表显示guo中所有的文件、创建新文件或者删除guo中现有的文件,或者将guo作为当前工作目录。第5至7个位置上的权限是rwx,表示root组的成员拥有和root一样的权限。第8至10位上的权限仅是r--,表示不是root的用户及不属于root组的成员只有对guo目录列表的权限。这些用户不能创建或者删除guo中的文件、执行junk中的可执行文件,或者将junk作为他们的当前工作目录。

2. Android应用程序权限申请

每个应用程序的APK包里面都包含有一个AndroidMainifest.xml文件,该文件除了罗列应用程序运行时库、运行依赖关系等之外,还会详细地罗列出该应用程序所需的系统访问。程序员在进行应用软件开发时,需要通过设置该文件的uses-permission字段来显式地向Android系统申请访问权限。

该文件的基本格式如下:

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android" 
  3.      package="cn.com.fetion.android" 
  4.      android:versionCode="1" 
  5.      android:versionName="1.0.0"> 
  6.    <application android:icon="@drawable/icon" android:label="@string/app_name"> 
  7.        <activity android:name=".welcomActivity" 
  8.                   android:label="@string/app_name"> 
  9.             <intent-filter> 
  10.                 <action android:name="android.intent.action.MAIN" /> 
  11.                 <category android:name="android.intent.category.LAUNCHER" /> 
  12.             </intent-filter> 
  13.         </activity> 
  14.    </application> 
  15.   <uses-permission android:name="android.permission.SEND_SMS"></uses-permission> 
  16. </manifest> 

如上述文件描述中加下划线的斜体部分,该文件的作用是说明该软件需要发送短信的功能。

值得注意的是:通过测试发现一种特殊的情况,应用程序可以在程序运行时申请root权限,如右图,在使用Android Terminal Emulator时尝试使用su命令切换到root用户。若用户已通过hacking的方式使得Android系统获得了root权限,则可以允许该程序以root用户权限执行;反之即算用户选择“允许”,也不能使程序以root用户权限执行。

授权要求

3. Android系统对应用程序权限申请的处理方式分析

对Android源代码中的如下文件进行分析:

(1) InstallAppProgress.java:其路径为\packages\apps\PackageInstaller\src\com\android\packageinstaller\InstallAppProgress.java;

(2) PackageInstallerActivity.java:其路径为\packages\apps\PackageInstaller\src\com\android\packageinstaller\PackageInstallerActivity.java;

(3) AppSecurityPermissions.java:其路径为\frameworks\base\core\java\android\widget\AppSecurityPermissions.java

总结得出如下图所示的Android系统对应用程序授权申请的处理流程:

(1) 进入处理应用程序授权申请的入口函数;

(2) 系统从被安装应用程序的AndroidManifest.xml文件中获取该应用正常运行需申请的权限列表;

(3) 显示对话框,请求用户确认是否满足这些权限需求;

(4) 若同意,则应用程序正常安装,并被赋予相应的权限;若否定,则应用程序不被安装。系统仅提供给用户选择“是”或者“否”的权利,没有选择其中某些权限进行授权的权利。