Open Core Interface - MLPI
MLPI-MotionLogicProgrammingInterface(mlpi4Java)  1.26.2
Security in MLPI

MLPI and MLPIS

Starting at version 1.17.0.0 MLPI SDK supports two different communication protocols that can be used either to perform a secure (MLPIS) or insecure communication (MLPI) with the target device. MLPIS is only supported by devices Wind River VxWorks release 6.9 (i.e. MLC CMLC75, XLC CML75 and MLC XM2) with firmware version MLC 14V18 and newer.

Secure communication (i.e. MLPIS) refers to the encryption of the communication with the target device, thus protecting the exchanged information across the network. In the case of insecure communication (i.e. MLPI) the communication with the target device is not encrypted, therefore, it can be easily read or manipulated if the network traffic were to be analyzed (for example: using Wireshark). It is highly recommended to use secure communication in order to enable secure connections. This is done by using the '-tls=active' option in the connect function . For more information see ApiLibConnect.

Note
It is important to keep in mind that MLPIS is not supported by all MLPI SDK libraries. For an overview of the supported libraries see Client versions of MLPI.
The establishment of an MLPIS connection is more exhaustive and requires more time than an MLPI Connection. This time depends on many factors such as network congestion and the properties of the credentials. The time required to establish an MLPIS connection with credentials with a key size of 2048 bits was measured in ~300 ms. For guidelines on MLPI(S) connection establishment strategies see Connection Strategies.

MLPI

MLPI employs the TCP/IP protocol. TCP is the most widely known and used connection-oriented protocol due to its high reliability that ensures that all information sent from a source is received on the target.

The information sent through this protocol is seen in the same format as it was sent by the source. Therefore, its use is recommended in cases where the security of the network is already ensured or in cases when data confidentiality is not required.

MLPIS

The MLPI SDK supports a second communication protocol: TLS. TLS is a cryptographic protocol that provides data confidentiality, integrity and client-server authentication. To implement this protocol both client and server must each have a private key and a certificate. The certificate contains the public key and additional information that allows to authenticate the owner of the private key. Unlike in TCP where we use the term connection to describe the established communication, in TLS the term session is used to refer to both the connection established between client and server and the information used to secure such communication.

The steps performed between client and server to perform a TLS connection establishment can be seen in the following image.

MLPIS-TLS.png

As seen above, both client and server exchange their certificates to be able to communicate with one another. The certificates are exchanged in order to authenticate the owner of the private key and in order to exchange the public key that is used to encrypt the session negotiation information. Once the session negotiation has been completed, a unique session key is generated that both client and server will use throughout the whole life-cycle of the session, thus ensuring long-standing security. It must be noted that in order to ensure the security of the communication the private key must always be kept secret and it is recommended to have only one private key per client/server.

Note
Since server version 1.17.0 the server credentials are required in order to secure the communication. This means that no mutual authentication is supported using both parties' credentials. Since server version 1.19.0 it is possible to install own credentials (i.e. private key and certificate) on the target device by replacing the current credentials with others that meet the following requirements.
  • Private Key requirements
    1. Key file must be named "RSA_MlpiCustomPrivKey.pem" and located in the folder "/OEM/ProjectData/KeyStore" for devices XM2 and "/ata0/ProjectData/KeyStore" for devices CML75.
    2. As the extension specified in the file name is ".pem", its content must comply with the Base64 encoding.
    3. Encryption algorithm RSA.
    4. Not password-protected.
  • Certificate requirements
    1. Must be generated using the "RSA_MlpiCustomPrivKey.pem" key.
    2. Certificate file must be named "MLPI_CustomPubCert.der" and located in the folder "/OEM/ProjectData/CertficiateStore/certs" for devices XM2 and "/ata0/rojectData/CertficiateStore/certs" for devices CML75.
    3. As the extension specified in the file name is ".der", its content must comply with the binary form.
    4. Not password-protected.

Generate security credentials for MLPIS

The secure credentials required to implement secure communication in MLPIS can be generated using the OpenSSL toolkit. This toolkit provides an open-source implementation of the SSL and TLS protocols and provides many more cryptographic operations (e.g. generate certificates, private and public keys, etc.). The OpenSSL Software Foundation provides the sources that can be compiled and installed. Once the installation has been completed the following steps need to be followed in order to generate the security credentials (i.e. private key and certificate).

Note
The following command descriptions and examples provide a simple and summarized picture of the operations provided by openssl. For information regarding additional or more complex features, please consult the openssl online documentation.
Other methods and tools can be used to generate the credentials. It is left to the discretion of the user. However, the requirements mentioned above must be fulfilled.

Generate private keys

The first element that must be generated is the private key, as all the additional elements (Certificate Signing Request and Certificate) are generated from it.The genpkey command is used to generate private keys with the specified configuration:

openssl genpkey
openssl genpkey -algorithm cryptAlgorithm -out privKeyFileName -outform privKeyFileFormat -pass pass:privKeyPwd -cipherName -pkeyopt optionName:optionValue
Parameters
[in]cryptAlgorithmEncryption algorithm: RSA or DSA.
[in]privKeyFileNameName of the file where the private key will be stored.
[in]privKeyFileFormatFile format of the key: PEM (Base64 encoding) or DER (binary). If not specified, the PEM format is used by default.
[in]privKeyPwdPassword used to protect the confidentiality and integrity of the private key.
[in]cipherNameCipher algorithm used to encrypt the private key (e.g. des, des3, rc4, etc.).
[in]optionName:optionValueAdditional key generation options. For both RSA and DSA the length of the private key in bits can be defined using the rsa_keygen_bits and dsa_paramgen_prime_len options respectively (e.g. rsa_keygen_bits:2048). If not specified, the length 1024 is used by default. Additionally, RSA allows to specify the public key exponent in its decimal or hexadecimal representation using the rsa_keygen_pubexp option (e.g. rsa_keygen_pubexp:65537).
Returns
In case of failure an error message is returned.
Example:
// Unencrypted RSA private key with length 1024 in DER format.
openssl genpkey -algorithm RSA -out rsaPrivKey1024.der -outform DER
Example:
// Unencrypted RSA private key using with length 2048 in PEM format.
openssl genpkey -algorithm RSA -out rsaPrivKey2048.pem rsa_keygen_bits:2048

It is also possible to generate a file with the genpkey command that contains all the configuration arguments for the generation of the private key. This is mandatory to generate a DSA private key. Additionally, it can be useful when generating multiple keys with the same configuration parameters.

The syntax to generate the configuration file is the following:

openssl genpkey -genparam
openssl genpkey -genparam -algorithm cryptAlgorithm -out configFileName -outform configFileFormat -pkeyopt optionName:optionValue
Parameters
[in]configFileNameName of the file that will contain the configuration arguments to be used in order to generate the private key.
[in]configFileFormatFile format of the configuration file (DER or PEM).
Returns
In case of failure an error message is returned.
Example:
// DSA key configuration. Any key generated with this file will have a length of 2048 bits.
openssl genpkey -genparam -algorithm DSA -out dsaKeyConfig.pem dsa_paramgen_prime_len:2048

After the configuration file has been created, it can be used to generate the private key with the genpkey command. The private key generated will have the settings defined in the configuration file.

openssl genpkey -paramfile
openssl genpkey -paramfile configFilleName -out keyFileName -pass pass:privKeyPwd -cipherName
Parameters
[in]configFileNameName of the file contains the configuration arguments to be used in order to generate the private key.
[in]keyFileNameName of the file where the private key will be stored.
Returns
In case of failure an error message is returned.
Example:
// Unencrypted DSA key generated from a predefined configuration file.
openssl genpkey -paramfile dsaKeyConfig.pem -out dsaPrivKey2048.pem

Generate Certificate Signing Request (CSR)

After the private key has been generated, the CSR must be created. The CSR contains the public key and organizational information that will be added to the certificate such as the company name, its location, etc. The CSR is most commonly provided to a Certificate Authority (CA) in order to request a certificate. However, it is also required in cases where no specified CA is defined and self-signed certificates are desired.

The req command is used to generate CSRs, self-signed certificates and it can also generate private keys. To generate a certificate first a CSR needs to be created.

openssl req -new
openssl req -new -digestName -keyform privKeyFormat -key privKeyName -passin pass:privKeyPwd -outform csrFormat -out csrName -passout pass:csrPwd
Parameters
[in]digestNameMessage digest used to sign the CSR (e.g. -sha256). To obtain a full list of the supported digest names, run the following command: openssl –digest-commands.
[in]privKeyFormatFormat of the private key (PEM or DER). If not specified, the PEM format is used by default.
[in]privKeyNameFile name of the private key from which the public key will be extracted in order to generate the CSR.
[in]privKeyPwdPassword required to extract the public key from the encrypted private key (only needed if the key is encrypted).
[in]csrFormatFile format of the CSR to be generated (PEM or DER)). If not specified, the PEM format is used by default.
[in]csrNameName of the file where the CSR will be stored.
[in]csrPwdPassword used to protect the confidentiality and integrity of the CSR.
Returns
In case of failure an error message is returned.
Example:
// Unencrypted CSR generated using an RSA private key with length 1024 in PEM format.
openssl req -new -sha256 -keyform DER -key rsaPrivKey1024.der -out rsaCSR1024.pem
Example:
// Unencrypted CSR generated using an encrypted RSA private key with length 2048 in PEM format.
openssl req -new -sha256 -key dsaPrivKey2048.pem -outform DER -out dsaCSR2048.der

After these commands are executed, the following information is requested: country name (2 letter code), state or province name, locality name, organization name, organizational unit name, common name, email address, challenge password (which should not be configured for certificates for the target device) and optional company name.

Generate self-signed Certificate

Once a CSR has been generated, a different syntax for the req command is used in order to generate a certificate.

openssl req -x509
openssl req -x509 -inform csrFormat -in csrName -passin pass:csrPwd -outform certFormat -out certName -days numberDays -set_serial serialNumber
Parameters
[in]csrFormatMessage digest used to sign the CSR (e.g. -sha256). To obtain a full list of the supported digest names, run the following command: openssl –digest-commands.
[in]csrNameFormat of the private key (PEM or DER). If not specified, the PEM format is used by default.
[in]csrPwdFile name of the private key from which the public key will be extracted in order to generate the CSR.
[in]certFormatPassword required to extract the public key from the encrypted private key (only needed if the key is encrypted).
[in]certNameFile format of the CSR to be generated (PEM or DER)). If not specified, the PEM format is used by default.
[in]daysNumberName of the file where the CSR will be stored.
[in]serialNumberPassword used to protect the confidentiality and integrity of the CSR.
Returns
In case of failure an error message is returned.
Example:
// Certificate generated using an RSA private key with length 1024 in PEM DER.
openssl req -x509 -keyform DER -key rsaPrivKey1024.der -in rsaCSR1024.pem -out rsaCert1024.pem -days 365
Example:
// Certificate generated using an encrypted DSA private key with length 2048 in PEM format.
openssl req -x509 -key dsaPrivKey2048.pem -inform DER -in dsaCSR2048.der -outform DER -out dsaCert2048.der -days 30

An overview of additional command line utilities provided by Openssl are available in https://wiki.openssl.org/index.php/Command_Line_Utilities.

Permission and user management

The MLPI has the possibility of user-specific account management based on the function layer, meaning a user account has a fixed set of permissions that allow it to execute only a fixed scope of MLPI functions on the control. The relation between the user accounts and their permissions are managed by a set of XML manifest files located on the control. The structure and organization of these files has varied in the last MLPI Versions and hence, special attention must be taken in case it is desired to modify such files manually.

Permission

All functions of the MLPI are bundled within functional groups, where each group is assigned to one explicit permission.

functional group A permission
mlpiLogicGetStateOfApplication MLPI_LOGICLIB_PERMISSION_APPLICATION_INFO
mlpiLogicGetOperationStateOfApplication
mlpiLogicGetTaskInfoOfApplication
mlpiLogicGetInfoOfApplication
functional group B permission
mlpiLogicSaveRetainOfApplication MLPI_LOGICLIB_PERMISSION_RETAIN_DATA
mlpiLogicRestoreRetainOfApplication
functional group C permission
... ...

Usage

When establishing the connection by calling mlpiApiConnect, the user account itself and the maximum number of logins of this user account will be checked by the system. Therefore, you have to give the username and the password of your desired account through the mlpiApiConnect function to the system. In case of a successful validation, you will get the corresponding permissions of this account for the complete session of this connection. If the maximum limit of logged in users of this account is reached, the function mlpiApiConnect will return with the error MLPI_E_LIMIT_MAX. In case the user is unknown, the function mlpiApiConnect will return with the error MLPI_E_PERMISSION. Furthermore, in case the user is not the owner of a permission of a functional group, he will get the error MLPI_E_PERMISSION on the invalid call of a function of this group.

A connection can be closed by an other connection with the assistance of the functions mlpiApiCloseConnectionByUid, mlpiApiCloseConnectionsByUser or mlpiApiCloseConnectionsByUri to protect dead locks caused by reaching the maximum number of concurrent logins. To prevent the closing of your connection by an other connection, use the attribute protection within your user account (accounts.xml) or use the same named option within your connection string of the function mlpiApiConnect (see MlpiApiProtection). If a connection runs in protected mode, the functions mlpiApiCloseConnectionByUid, mlpiApiCloseConnectionsByUser or mlpiApiCloseConnectionsByUri return the error MLPI_E_RD_WR_PROTECTION on call.

Manifest

The user accounts, their attributes and the associated permission sets are defined in manifest files. In server versions lower than 1.20.0.0 the name of this manifest is accounts.xml. Whereas in server versions 1.20.0.0 - 1.26.0.0 the name of this manifest is users.xml. Starting in server version 1.26.0.0 the users and permissions are divided in two different manifest files named users.xml and groupsV2.xml.

Note
The location and handling of the manifest file itself has been changed in the MLPI Server Version 1.19.0.0 and Version 1.26.0.0. Additionally, some of the methods concerning this file have also been deprecated on this version and hence, the similarities and differences with regards to functionality are highlighted in the following subsections.
MLPI Server Version 1.19.0.0 : Changes in the account manifest (i.e. accounts.xml) manages not only the access to specific MLPI libraries, but also to the following communication protocols: FTP, SFTP and SSH. Any user specified in the account manifest can connect to the target control with these protocols using valid credentials (i.e. username and password) defined in the manifest.
MLPI Server Version 1.26.0.0: The funcionality defined by the user management defined in 1.19.0.0 has been extended in order to manage the access to certain permissions (i.e. Per individual MLPI Library or per communication protocol) by assigning group permissions rather than individual permissions to individual users. In order to assign permissions to a user. The desired permissions must first be assigned to a group. Afterwards a user must be assigned to the specific group in order to inherit the desired permissions.

Manifest since server version 1.26.0.0

Note
In version 1.26.0.0 a new permission management has been implemented. In this context some permissions have been combined in order to improve usability. The individual assignment of permissions to individual users implemented in older server versions has been deprecated. The new permission management allows to create and manage groups of users. The permissions must be assigned to specific groups, which inherit their permissions to the users members of such groups. Information regarding the groups and their permissions is available on the target device on a group manifest file (i.e. groupsV2.xml) located on the OEM partition (MLPI_PATH_PROJECTDATA). Information about the users, as well as their group memberships is found in the new user manifest file (i.e. users.xml) also located on the OEM partition. This new user manifest file replaces the deprecated user manifest (i.e. accounts.xml). The MLPI Library AccessControlLib provides the functionality to create and manage users and groups, as well as to assign their corresponding memberships and permissions.

The default user (Version 4) and group (Version 2) manifests are located at the root of the Project Data folder located in the OEM partition(MLPI_PATH_PROJECTDATA) of the control for server versions 1.26.0.0 or higher. Older Manifest versions can be ported to their newer version by placing them in this directory and rebooting the system after deleting any preexisting manifest (i.e. users.xml and groups.xml). It is important to highlight that a firmware version 14V22 or higher must be installed in the control in order to successfully perform the version update of the manifest files.

Unlike in older MLPI Server Versions, the OEM partition is the only valid location for manifest files. This has been modified in order to comply with the new user and permission management supported by the MLPI library AccessControlLib. The manifest in the SYSTEM partition (MLPI_PATH_SYSTEM) defines the default users when the factory settings are loaded. Please do not modify the SYSTEM user and group manifests!

Note
In order to reuse an older accounts.xml, it is necessary to copy this file into the folder "ProjectData" (MLPI_PATH_PROJECTDATA) and delete the preexisting manifest files (i.e. users.xml and groups.xml) if they exist and reboot the control. After the reboot, these files will be parsed into their newer manifest versions.

Additionally, the manual creation of a user (for example directly modifying the user manifest file located on the target control using FTP) is highly discouraged and it is recommended to add and manage new users and groups using the methods provided by the MLPI Library AccessControlLib.

The following steps should be carried out in order to create a completely new and usable user and group:

  • Create a new group (only necessary if the desired group does not exist already)
  • Assign desired permissions to group (only necessary if the desired permission is not assigned to the desired group)
  • Create new user (only if the desired user does not exist already)
  • Add desired user as member of the desired group (only if the desired user is not a member of the desired group already)
Note
In order to add a new user manually (as performed in (Manifest for server versions before 1.19.0.0)), it is important to ensure that the assigned user id is unique and that the argument lastID from the user manifest (i.e. users.xml) is up to date.
You need the MLPI or MLPIS permission to use the protocol, if you donĀ“t give the group this permission you cannot use any MLPI(S) function.
<accounts version="4" type="mlpi" xmlns="./accounts.xsd" lastID="101">
<account id="1" user="boschrexroth" hash="fc041cce84e729770169f79ea494a71656a82694c930c943a33b4123040c2ee0f0c2e73ff3bbc158b09031e2d4ca2a2092bc8fe57e984ec88c1bd77fcce7042d">
<account id="100" user="supervisor" hash="a72edbdc3e66dc3f0f84500c4a0df1ab640f47e95ae4e7c76de3398854146f33fcabe0a9861a6896d9a78c15273f2c1996e88b14e92a99d4b883af9a5c98c9c6" userMaxNumber="1" protection="2"/>
<account id="101" user="example" hash="73efafbcdc33b4ed05d233e0ebed165ceff427316211795aeb46980271fb9811408ea1a3a1d8d506e744d80bfb3a7099eaeb8c22f89191da3579a2bcbb38f5ce" protection="1"/>
</accounts>
<groups version="2" lastID="101">
<account id="1" name="engineer">
<facility name="COMMUNICATION">
<permission name="OPCUA"/>
<permission name="MLPIS"/>
<permission name="MLPI"/>
<permission name="SSH"/>
<permission name="SFTP"/>
</facility>
<facility name="APILIB">
<permission name="DEBUG"/>
<permission name="MANAGEMENT"/>
<permission name="STATUS"/>
</facility>
<facility name="LOGIC">
<permission name="WRITE"/>
<permission name="READ"/>
<permission name="CONTROL"/>
<permission name="CONFIG"/>
<permission name="INFO"/>
</facility>
</account>
<account id="100" name="IO_Users">
<facility name="COMMUNICATION">
<permission name="MLPIS"/>
</facility>
<facility name="IO">
<permission name="UPDATE"/>
<permission name="WRITE"/>
<permission name="READ"/>
<permission name="INFO"/>
</facility>
</account>
<account id="101" name="OPCUA_Users">
<facility name="COMMUNICATION">
<permission name="OPCUA"/>
</facility>
</account>
</accounts>

We have default group called "engineer". This group contains the necessary permissions required by the user indraworks. It is not recommended to do changes or delete this group. In order to add a user into a group, the method mlpiAccessControlAddUserToGroup must be used. By following these steps, the manual manipulation of the manifest file and the reboot of the control are not necessary.

Note
The user management requires at least one user to be a member of the "engineer" group. Otherwise, the operation of indraworks is not possible.
The debug tool WinView uses the account "MlcTrending" and needs the factory settings of permissions for faultless operation.

Manifest server version higher than 1.19.0.0 and lower than 1.26.0.0

The default manifest is located at the root of the Project Data folder located in the OEM partition(MLPI_PATH_PROJECTDATA) of the control and now has the version 3. Older Manifests (i.e. Version 2) can be ported to the newer version (i.e. Version 3) by placing them in this directory and rebooting the system. Unlike in older MLPI Server Versions, this manifest file is the only one that is located in the control. This has been modified in order to comply with the new user management supported by the MLPI library AccessControlLib. The manifest in the SYSTEM partition (MLPI_PATH_SYSTEM) defines the default users when the factory settings are loaded. Please do not modify the SYSTEM account manifest!

Note
Since version 1.19.0.0 we do not support the merge options any more! You can reuse your old manifest (version 2) but we will automaticly do a permantent merge and generate a new accounts.xml out of both files. The control uses only that new generated file. So if you want to do changes on the manifest you have to modify this one.

Additionally, the creation of a manual user is highly discouraged and it is recommended to add new users to the manifest file by using the methods provided by the AccessControlLib. Although it must be noted that the new users added with this library will contain no MLPI Permissions and hence, the permissions must be added by manually modifying the manifest file (see Manifest for server versions before 1.19.0.0) after the user has been added. Afterwards, the control must be rebooted in order for the changes to be applied or you can use just use the function mlpiApiUserAccountControlReload. If you still want to add the user manually you can do it in the same way like in the old versions (Manifest for server versions before 1.19.0.0), but you have to ensure that the id of the user is unique and you always have to update the lastID item to the last used user id:

Note
For security reasons we do not support the "empty-guest-user" anymore! Setting plaintext passwords is also not possible anymore!
<accounts version="3" type="mlpi" xmlns="./accounts.xsd" lastID="101">
<account id="1" user="boschrexroth" hash="fc041cce84e729770169f79ea494a71656a82694c930c943a33b4123040c2ee0f0c2e73ff3bbc158b09031e2d4ca2a2092bc8fe57e984ec88c1bd77fcce7042d">
<account id="100" user="supervisor" hash="a72edbdc3e66dc3f0f84500c4a0df1ab640f47e95ae4e7c76de3398854146f33fcabe0a9861a6896d9a78c15273f2c1996e88b14e92a99d4b883af9a5c98c9c6" userMaxNumber="1" protection="2">
<library name="mlpiApiLib">
<permission name="MLPI_APILIB_PERMISSION_ALL">true</permission>
</library>
...
</account>
<account id="101" user="example" hash="73efafbcdc33b4ed05d233e0ebed165ceff427316211795aeb46980271fb9811408ea1a3a1d8d506e744d80bfb3a7099eaeb8c22f89191da3579a2bcbb38f5ce" protection="1">
<library name="mlpiApiLib">
<permission name="MLPI_APILIB_PERMISSION_ALL">true</permission>
<permission name="MLPI_APILIB_PERMISSION_CONNECTION_CLOSE">false</permission>
</library>
<library name="mlpiLogicLib">
<permission name="MLPI_LOGICLIB_PERMISSION_ALL">false</permission>
<permission name="MLPI_LOGICLIB_PERMISSION_APPLICATION_INFO">true</permission>
<permission name="MLPI_LOGICLIB_PERMISSION_SYMBOL_INFO">true</permission>
</library>
...
</account>
...
</accounts>

A default group called "engineer" is handled by the user management. This group contains the necessary permissions required by the user indraworks. It allows to provide the same MLPI Permissions as those defined for the indraworks user to all the users that are assigned to it. In order to add a user into a group, the method mlpiAccessControlAddUserToGroup must be used. By following these steps, the manual manipulation of the manifest file and the reboot of the control are not necessary.

This default group also allows to remove the indraworks user and add new users with different login credentials for their use in indraworks (since Indraworks-Version 14V20).

Note
The user management requires at least one user to be a member of the "engineer" group. Otherwise, the operation of indraworks is not possible.
The debug tool WinView uses the account "MlcTrending" and needs the factory settings of permissions for faultless operation.

Manifest for server versions before 1.19.0.0

The MLPI SDK provides a template of the manifest accounts.xml in the folder "..\%MLPI-SDK%\data\...". The template contains a factory preset of user accounts and permissions, which have to be adapted and placed on the OEM partition by the system integrator. The adaption of the account manifest accounts.xml will be supported by the XML scheme file accounts.xsd, which is located at the same place. It's recommended to use it to simplify editing and to verify the contents of your account configuration.

The functional groups and the according permissions are documented within the chapter "Version and Permission" of the regarding library documentation (e.g. "LogicLib": LogicLibVersionPermission). The function groups of a library can be enabled at once by using the library-global permission key "MLPI_*LIB_PERMISSION_ALL".

<accounts version="2" type="mlpi" merge="add" xmlns="./accounts.xsd">
<account user="supervisor" hash="a72edbdc3e66dc3f0f84500c4a0df1ab640f47e95ae4e7c76de3398854146f33fcabe0a9861a6896d9a78c15273f2c1996e88b14e92a99d4b883af9a5c98c9c6" userMaxNumber="1" protection="2">
<library name="mlpiApiLib">
<permission name="MLPI_APILIB_PERMISSION_ALL">true</permission>
</library>
...
</account>
...
</accounts>

Each functional group can be selectively picked by deactivation or deleting of the library-global permission key "MLPI_*LIB_PERMISSION_ALL" and using a list of the desired permission keys. You can also switch off single permissions by using enabled "MLPI_*LIB_PERMISSION_ALL" and followed by disabled single permission keys.

<accounts version="2" type="mlpi" merge="add" xmlns="./accounts.xsd">
<account user="supervisor" hash="a72edbdc3e66dc3f0f84500c4a0df1ab640f47e95ae4e7c76de3398854146f33fcabe0a9861a6896d9a78c15273f2c1996e88b14e92a99d4b883af9a5c98c9c6" userMaxNumber="1" protection="2">
<library name="mlpiApiLib">
<permission name="MLPI_APILIB_PERMISSION_ALL">true</permission>
</library>
...
</account>
<account user="example" password="example" protection="1">
<library name="mlpiApiLib">
<permission name="MLPI_APILIB_PERMISSION_ALL">true</permission>
<permission name="MLPI_APILIB_PERMISSION_CONNECTION_CLOSE">false</permission>
</library>
<library name="mlpiLogicLib">
<permission name="MLPI_LOGICLIB_PERMISSION_ALL">false</permission>
<permission name="MLPI_LOGICLIB_PERMISSION_APPLICATION_INFO">true</permission>
<permission name="MLPI_LOGICLIB_PERMISSION_SYMBOL_INFO">true</permission>
</library>
...
</account>
...
</accounts>

You can specify the password for an account either in plain text by using the attribute password or by using a hash value with the attribute hash. It is highly recommended to use the hash value and not the plain password approach. The latter is only helpful for debugging purposes. You can generate hashes from passwords by using the program hashmaker.exe in the folder "..\%MLPI-SDK%\data\" of the MLPI-SDK, the linked local HTML site at the MLPI SDK overview site (section "Hash calculator") or any other Whirlpool hashing tool.

For example, use the command line tool to generate a hash value for the password "gothamcity".

%MLPI-SDK%\data\hashmaker.exe gothamcity

Now copy the resulting hash value to the manifest accounts.xml.

Hint:
hashmaker.exe copies the resulting hash value to the clipboard, so you do not need to type it to the accounts.xml manually.
<accounts version="2" type="mlpi" xmlns="./accounts.xsd">
<account user="batman" hash="0f2764ae433afe1235acb97cc2898fbbf4e7c0dcf79e321124579d667afa47510b989f528c2ddfe4ed64cff64e102897c9c07abceeda390face0ff145c6c9c4f" userMaxNumber="1" protection="2">
<library name="mlpiApiLib">
<permission name="MLPI_APILIB_PERMISSION_ALL">true</permission>
</library>
...
</account>
...
</accounts>

The account of the user "batman" is now secured by the password "gothamcity". See mlpiApiConnect for login details.

Note
There is no chance to calculate from the hash value back to your password. Thus, it is more secure to store the password as hash value instead of plain text. Nevertheless, it is recommended to choose non simple passwords which contain numbers and letters in lower and upper case. Otherwise it will be easier to just guess the password.

The default manifest is located at the root of the SYSTEM partition (MLPI_PATH_SYSTEM) of the control. As a backup, this manifest should be left untouched without any modification. The system integrator has the possibility to place a second adapted manifest accounts.xml at the root of the OEM partition (13VRS, MLPI_PATH_OEM) resp. at the root of the project data folder (14VRS, MLPI_PATH_PROJECTDATA) of the control. During booting or reloading, the control will search for the manifest on this location at first and at second on the SYSTEM partition.

Note
The control parses the manifest once during boot-up sequence. Changes on a manifest will be recognized only on reboot or if explicitly triggered by the mlpi function mlpiApiUserAccountControlReload.
The development environment IndraWorks uses several accounts starting with "indraworks" and needs the factory settings of the whole accounts for faultless operation.
The debug tool WinView uses the account "MlcTrending" and needs the factory settings of permissions for faultless operation.

Since version 1.4.0.0, the MLPI server on the control supports the merge of account manifests. To activate the merge of a manifest, you have to use the XML attribute merge followed by the XML attribute value add or replace in your manifest within the XML node accounts. This feature makes it possible to easily add new accounts through a new accounts.xml on OEM partition (MLPI_PATH_OEM) without taking care of the accounts of the delivered system accounts on the SYSTEM partition (MLPI_PATH_SYSTEM).

<accounts version="2" type="mlpi" merge="add" xmlns="./accounts.xsd">
<account user="supervisor" hash="a72edbdc3e66dc3f0f84500c4a0df1ab640f47e95ae4e7c76de3398854146f33fcabe0a9861a6896d9a78c15273f2c1996e88b14e92a99d4b883af9a5c98c9c6" userMaxNumber="1" protection="2">
<library name="mlpiApiLib">
<permission name="MLPI_APILIB_PERMISSION_ALL">true</permission>
</library>
...
</account>
...
</accounts>
Note
The first loaded manifest accounts.xml (generally loaded from OEM partition (MLPI_PATH_OEM) or, at second, from SYSTEM partition (MLPI_PATH_SYSTEM)) defines the default merge operation for all further account manifests, which didn't do this by itself through separately using the XML attribute merge.
Merge operation Description
add The MLPI server tries to add the accounts of the manifest to the user account control (UAC). If an account is already present, this new account will be ignored.
replace The MLPI server tries to add the accounts of the manifest to the UAC. If an account is already present, this old account will be replaced by the new one.
n/a The MLPI server use the preset of the first loaded account manifest generally loaded from OEM partition (MLPI_PATH_OEM) or, at second, from SYSTEM partition (MLPI_PATH_SYSTEM).
Note
The default manifest "accounts.xml" located at the root of the SYSTEM partition (MLPI_PATH_SYSTEM) does not use the XML attribute merge so the system integrator has the possibility to define its default behavior by using the XML attribute merge within the manifest "accounts.xml" located at the root of the OEM partition (MLPI_PATH_OEM).

Furthermore, the MLPI supports the additional loading and unloading of user-defined account manifests by using mlpiApiUserAccountControlLoadAccounts and mlpiApiUserAccountControlUnloadAccounts after the automatic loading of the account manifests accounts.xml from the OEM partition (at first) and the SYSTEM partition (at second).