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 (see Signed MIDlets). 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.