When developing an application using the FC API, it is important
to take into account the security implications of the API. File operations
are restricted with the aim of protecting the user's private data
and the overall system security. File operations can be executed only
if the required permission has been acquired before; otherwise a SecurityException
will be thrown. It is important to be
aware of this and include a catch SecurityExceptions
statement when appropriate.
MIDP 2.0 MIDlets are either untrusted or trusted. With untrusted MIDlets, the device cannot assure the MIDlet's origin and integrity, and therefore calling restricted APIs is not allowed without explicit user permission. This means that whenever you need to access a file or a directory, a user prompt will appear and the user must explicitly authorize the operation.
With trusted MIDlets, the device can determine their origin and
integrity by means of X.509 certificates. These MIDlets may acquire
permissions automatically depending on the security domain settings
they were installed with. In addition, the MIDlet needs to include
the requested file permissions in its Java Application Descriptor
(JAD) file under the MIDlet-Permission
property.
Two permissions have been defined in relation to the FC API:
javax.microedition.io.Connector.file.read
This permission is necessary for opening files
in READ mode and to obtain input streams for those files. It is also
required when registering listeners with the FileSystemRegistry
class.
javax.microedition.io.Connector.file.write
This permission is required to open files in WRITE
mode and for opening output streams to those files. In addition, operations
such as delete
, mkdir
, and
others need the write permission.
If you open a file in READ_WRITE mode, you need both permissions.
These permissions are contained in the Read User Data Access
and Write User Data Access
function groups.
Permissions are granted or denied depending on which security domain the MIDlet was installed in. Some domains may fully grant those permissions and others may allow them only with explicit user approval. The definition of what permissions are allowed for each domain is implementation-specific. Nevertheless, it is expected that for the third-party and untrusted domain the permissions mode will be as shown in the table below:
Function group |
Trusted third-party domain |
Untrusted domain |
||
Default setting |
Allowed settings |
Default setting |
Allowed settings |
|
Read User Data Access |
Oneshot |
Session, Blanket, Oneshot, No |
Oneshot |
Oneshot, No |
Write User Data Access |
Oneshot |
Session, Blanket, Oneshot, No |
Oneshot |
Oneshot, No |
In practical terms, the table tells that an untrusted MIDlet will show a user prompt every time a connection to a file or directory is created. Furthermore, if the connection is opened in READ_WRITE mode, there will be two prompts, one for both permissions. In the case of trusted third-party MIDlets, the situation is the same but the user has the option of manually changing this setting to session and therefore be asked only once while running the MIDlet. It is also important to notice that the permissions are given in a file-to-file basis. This means that the user may be prompted for each file or directory that is being accessed. This situation is particularly noteworthy for MIDlets such as the one in this example, which traverses the file system and thus gets multiple user prompts. This situation makes a strong point for why MIDlets should be signed when using restricted APIs.
In addition, there is an extra layer of restrictions with
respect to file access. Depending on the security domain the MIDlet
has been assigned during installation, it will have access to a subset
of the file system. This is designed to protect the user data and
prevent damage to the operating system. In particular, MIDlets located
in the trusted third-party and untrusted domains have
access only to a set of designated public directories including those
for images, videos, public files, and a private directory assigned
to each MIDlet for its own usage. This is one reason why using virtual
roots is recommended since access to the Images/
root may be allowed but doing traversal from c:/
to c:/data/Images/
may not be allowed, because c:
could not be accessible by a MIDlet.
Several
file-related operations check if the appropriate security permissions
have been acquired, but you should be careful in particular when the Connector.open()
method is called. After a FileConnection
has been created and the appropriate permission has been granted,
it could be assumed that the permissions will hold for other operations
requiring the same permission. For instance, once a FileConnection
has been created for writing, invoking delete
should also have been authorized. If the FileConnection
has been created with a read permission and the delete()
method is called, the write permission will be needed and the user
will be prompted if necessary.
The setFileConnection()
method will also check for permissions to those files, depending
on which mode the original FileConnection
was
created. This is quite logical since setFileConnection
changes the current connection to point to a different file or directory.