Other system features

This topic includes the following DBL features:

Data encryption


This section discusses the encryption of data at the application level. For information about encrypting data transferred over a network, see Using xfServerPlus encryption and Using client/server encryption.

With the number of security regulations on the rise, data encrypting has become a critical requirement for most application developers. As of version 9.3, Synergy DBL enables you to encrypt and decrypt sensitive data using industry standard cipher techniques. This is accomplished on an on‑demand basis using a set of Synergy subroutines that encrypt and decrypt a specified data region. You determine which data is encrypted as well as how it is encrypted.

The Synergy data encryption feature interfaces with a third‑party library, OpenSSL, to provide SSL support. We use PKCS #5 (Password‑Based Cryptography Specification) in conjunction with PBKDF2 key derivation function (an ISO standard) provided by OpenSSL. To learn more about PKCS, visit tools.ietf.org/html/rfc2898.

Setting up your system for encryption

Follow these steps to set up your system to use encryption. For details on which version of OpenSSL is required for your operating system, see OpenSSL requirements. For additional information on OpenSSL, see Synergex KnowledgeBase article 100001979.

1. Install OpenSSL.
2. Ensure that the OpenSSL shared libraries are in the correct location or have been added to the correct path.

Encrypting and decrypting data

The DATA_ENCRYPT and DATA_DECRYPT routines encrypt and decrypt data using the data and password buffers that you pass to them. Optionally and recommended, the salt and IV arguments can be used to further enhance security. You can use the DATA_SALTIV routine to generate pseudorandom values that are appropriate for use.


As with the password, the same salt and IV used to encrypt the data is required to decrypt it, so these values must be saved off. However, the salt and IV don’t need to be kept secret.

The salt is used to derive the encryption key from the password, whereas the IV is used to randomize the resulting encrypted data. The encryption key used to encrypt/decrypt the data is immediately discarded by OpenSSL. Changing the keys that are used can be accomplished by altering either the password or the salt before encrypting. Additional key derivation parameters (iteration and key length) are kept internal and are set appropriately for the requested encryption algorithm. Supported encryption routines include 3DES‑CBC (Triple DES) and AES‑CBC. (For syntax information, see DATA_ENCRYPT, DATA_DECRYPT, and DATA_SALTIV.)

Ciphers process data in blocks. If the length of the data isn’t a multiple of the cipher block size, DATA_ENCRYPT and DATA_DECRYPT use PKCS padding to pad it. Bytes of padding (between 1 byte and the number of bytes in a cipher block) are always added to the data when it is encrypted and then removed when it is decrypted. When using PKCS padding, the unencrypted data can be any size, but the encrypted data is always a multiple of cipher block size; PKCS padding does not allow in‑place encryption even when the data is a multiple of the cipher block size.

To encrypt and decrypt data without changing its size (or for in‑place encryption), you can suppress padding, but the data must be a multiple of cipher block size. To suppress padding, pass a 0 value to the DATA_ENCRYPT and DATA_DECRYPT routine’s pad argument. If you suppress padding to encrypt a piece of data, you must also suppress padding when you decrypt the same piece of data, or the decryption will fail with an “Argument specified with wrong size” error ($ERR_ARGSIZ).


In‑place encryption is not allowed unless you explicitly suppress padding.

Cipher block sizes are as follows:


8 bytes


16 bytes

You can determine the size of the encrypted data by passing the len argument to DATA_ENCRYPT with no destination argument, which applies the following formulas. (Padding is either 1 or 0.)


8 * (%TRUNC(data_size / 8) + padding)


16 * (%TRUNC(data_size / 16) + padding)


Index data should only be encrypted if it is used for lookup only (READ with MATCH:Q_EQ) and not for index sequences (READS) and made into an alpha field of the size of the encrypted region. The key used for the lookup would be encrypted on the client first before passing to a READ or FIND statement. Any file that uses encryption contains binary data and can only be unloaded/reloaded from a counted file.

Access to encrypted data in a Synergy file is not supported by xfODBC. Make sure you mark encrypted fields as “Excluded by ReportWriter” in the repository.

To implement Synergy data encryption,

1. Decide what type of encryption you want to use and which fields should be encrypted. For example, you might choose to use AES‑128 encryption to encrypt a field in your customer master record. You can allow for padding by inserting a “pad” field directly after the field and then declaring an overlay field to encompass both the original field and the pad field. Make sure when encrypting that the source doesn’t include the pad field. If the field is a multiple of the cipher block size, you may also suppress padding.
2. If you want to maximize the effectiveness of the cipher by including a random salt and/or IV, call the DATA_SALTIV routine and save the resulting value(s).
3. Before writing data to your master file using the STORE and WRITE statements, call the DATA_ENCRYPT routine with a user password and the salt and/or IV you generated in step 2, if applicable.
4. After reading data from your master file using the READ and READS statements, call the DATA_DECRYPT routine with the same user password, salt, and/or IV that you used to encrypt the data.
5. Convert your master file (if one existed before) to the new record structure. (Note that you must construct a program or routine to perform this conversion; no utility exists to convert the file automatically.)

Data at rest encryption

Synergy allows you to perform data at rest encryption for protected data (for example, credit card, Social Security, NHI, and bank account numbers) as long as you have the following:

For ISAM files, key data encryption is possible where the keys provide direct keyed access (rather than ordered retrieval). Each key must be separately encrypted, with the key size being the encryption boundary. (When updating an application to use this feature, it is likely that you'll need to change key size.) Keys should be located together to allow the remaining non-key data to be encrypted as a single entity. Encrypted keys should be defined as alpha keys.

Note the following:


As of version 9.1, Synergy DBL provides strong prototype validation of system‑supplied routines at compile time. This means that the compiler compares each system‑supplied routine used in your program to its prototype to ensure it has the correct number and type of arguments, correct return type, and so on. (If you need to relax some of the strong prototype validation, use the ‑qrelaxed option(s) when you compile.)

Synergy .NET code that you write is always strongly prototyped. For traditional Synergy object‑oriented code, strong prototyping is required and takes place within a compilation unit at compile time. However, outside a compilation unit, such as when you use multiple dbl commands, you must generate prototypes with the Synergy Prototype utility so that validation can take place.

Traditional non‑object‑oriented code can also be strongly prototyped using the Synergy Prototype utility. Doing so will ensure that calls match their routine definitions, which enables you to detect more problems at compile time rather than waiting until runtime. If a prototype exists, the compiler will check the signature of the prototype to ensure it matches the declaration.

For nonprototyped routines in the same compilation unit, the compiler will automatically perform weak prototype checking. This means the compiler will issue warnings based on the local definitions that are available at compile time. The amount of checking that takes place depends on the information available to the compiler. (If you need to relax some of the weak prototype validation, use the ‑qrelaxed:local option when you compile.)

See Synergy Prototype utility (dblproto) for more information on prototyping.


An often‑overlooked developer tool is the Synergy DBL Profiler. The profiler provides information that enables you to analyze the resources required by your application. It can help you significantly improve application performance by identifying the areas that are not as efficient as they could be.

Two profiling techniques are available:

You can also exclude specific routines from the profiler trace by specifying an exclusion list. By default, the profiler uses an exclusion list for the UI Toolkit input routines (WND:tkexclude.txt).

Profiling is enabled either by setting system option #40, #41, or #52 and using the profiling compiler option (‑u on Windows and UNIX or /profile on OpenVMS) or by setting system option #42. (Refer to Synergy DBL Profiler for the distinctions between these system options and under what circumstances you would want to use each one.) When you execute your program, profiling information is stored in a file called profile.dat. You can then run the profile or profline utility (depending on whether you are using routine profiling or line profiling) to produce a report of the results.


You can send messages between routines using the SEND and RECV statements. Synergy DBL provides two types of message facilities to process these messages: the local message facility (which is the default) and the Synergy message manager.

Using these message facilities, your program can communicate with other programs that are currently running or that will be running soon. For example, a program can send messages that affect how processing will be performed by programs to which it subsequently chains.

Both message facilities maintain local, group, and global queues. If you only use the local message facility, messages are only available to the current job stream. Routines are in the same job stream if they are called as subroutines or functions or if they are chained to. On OpenVMS, routines that are chained to are only considered to be in the same job stream if the program is bound. Once the runtime terminates, message queues are reinitialized.

If the local message facility is sufficient for your needs, we recommend using it rather than the Synergy message manager, which can incur additional processing overhead.

Differences between the message facilities

Local message facility

The local message facility is maintained by the runtime. Once the runtime terminates, all messages in the local message facility are lost.

Synergy message manager

Unlike the local message facility, the Synergy message manager (which is the Synergy DBL daemon on UNIX) enables you to send messages between processes. The Synergy message manager is a detached program that retains and maintains your messages. Even after the runtime terminates, the messages still exist, and you can run another program and receive those messages.

To use the Synergy message manager on UNIX, you must set system option #7 with the DBLOPT environment variable. If you don’t set option #7, Synergy DBL uses the local message facility instead of the Synergy message manager for SEND and RECV statements. See SEND and RECV for more information about sending and receiving messages.

On OpenVMS, the Synergy message manager is used by default. It writes errors to the log file DBLDIR:dblmsgctl.log. To disable the messaging facilities, set system option #47. The message manager can buffer up to 32000 messages.

On Windows, there is no Synergy Message Manager; Synergy DBL uses only local queues.

Synergy DBL messages and message queues

Each Synergy DBL message is identified by a combination of the terminal number to which it is directed and a message ID of one to six characters (or one to thirty‑nine characters on OpenVMS). If a SEND statement doesn’t specify a terminal number, the resulting message’s terminal identification includes the number of the terminal that initiated the program.

Local messages (UNIX only)

On UNIX, each terminal running a Synergy program has its own local message queue into which messages are inserted. Messages are retrieved from this queue in “first in, first out” order, according to message ID. Each message in a terminal’s local queue is called a local message.

By default, if you don’t specify a terminal number in a SEND statement, the message is inserted into the local message queue unless system option #1 or #13 is set. These options are explained in more detail below

Group and global messages

Sometimes you’ll want to send a message that has an ID but that is not directed to any particular terminal. You can use either group messages or global messages for this purpose. If you are sending to or from a detached process, you need to use a group or global queue and the Synergy message manager.

A global message can be received by any program that explicitly specifies the correct message ID in its RECV statement. Synergy DBL provides one global message queue for your system. Any message directed to terminal number 255 is inserted into the global queue and can be retrieved by referencing the message’s ID.

A group message can be received by any program specifying the correct message ID and running under the same group number as the sending program. Synergy DBL provides one group message queue for each group (which consists of a unique project and programmer number combination for each account). Any message directed to terminal number 254 is inserted into the group queue.

If you specify system option #13 with the DBLOPT environment variable, a SEND statement that does not specify a terminal number sends the message to terminal number 254 (the group message queue) by default. If you specify system option #1, the message goes to terminal number 255 (the global message queue) by default. Option #13 supersedes option #1. Therefore, if you specify both options, option #1 is ignored.

If you need to send a message to a program that will be running in the future, send it to a group or global message queue using the Synergy message manager. Programs whose terminal number is negative (for example, detached processes or batch jobs) use a global message queue by default.

On OpenVMS, group messages are the same as global. Sending a message to terminal ‑1 is the same as sending to the global queue.

Receiving messages

Unless the DFLAG subroutine’s runtime option flag 1 is set, the RECV statement begins searching for a requested message ID in the local queue for that process. If no message ID is specified, RECV assumes that the message ID is [SELF]. If RECV can’t find a message that matches the specified ID, it searches first in the group message queue and finally in the global message queue for the first message with the specified ID.

If RECV can’t find the message in any of these queues, it returns a “message not found” status. You can also use the DFLAG subroutine to indicate that your program should wait for the requested message to become available if no message exists. If you set DFLAG’s runtime option flag 2, your program waits for the message and does not signal the “message not found” status. (See DFLAG for more information.)

By default, the RECV statement searches all three message queues in the order described above. However, you can use the RCFLG subroutine to disable the searching of any queue for a particular program. RCFLG enables you to change the searching algorithm of the Synergy message manager by setting one or more of its receive option flags. See RCFLG for more information.

Special message IDs

Both message facilities recognize two special message IDs: [SELF] and [INIT].

A [SELF] ID in a SEND or RECV statement is interpreted as one of the following:

On Windows and UNIX, an [INIT] ID in a SEND statement causes the message facilities to discard all messages currently contained in the local message queue. When using the Synergy message manager, you can use [INIT] to restore the environment to a known state after a Synergy program terminates abnormally.

Device licensing (.NET)

With device licensing, Synergy applications use a cloud service for licensing. Device licensing enables you to license applications on mobile devices. It can also be used on non-device platforms — such as Windows servers, desktops, or laptops — that don’t have local Synergy licensing or persistent access to a Synergy license server.

Device licensing is supported for Synergy .NET applications running under the .NET Framework on Windows and is required for Synergy .NET Standard libraries in Universal Windows Platform (UWP) apps. For information on developing with Synergy .NET, see Synergy .NET Development.

.NET Framework version 4.5 or higher is required for development and must be installed if you are deploying for .NET Framework on a Windows platform.

Getting started

1. Contact Synergex to register as a device license subscriber. (This involves designating one or more “License Administrators” and “License Developers” for your company.)
2. From the Device Licenses section of the Synergex Resource Center, select the Create New App button. This adds a new device application to the list and creates a “development” license block for internal testing purposes. (An email containing the GUID and public key for the new application, as well as the default token/password, will be sent to all License Developers for your company.)
3. Edit the device application (in the Resource Center) to add a description. (Although this is not required, we highly recommend it if you have more than one application, so you can easily tell them apart.)
4. Code your application to support device licensing by implementing the device license interface. (See Implementing device licensing and Synergex.SynergyDE.DeviceLicensing.ISynergyDeviceCallback.)

You can handle device activation in one of the following ways:

5. Contact Synergex to assist you with the testing of your device‑licensed application following a detailed device licensing test plan. Coordinated testing with Synergex allows you to test both success and failure scenarios.
6. When you are ready to deploy your application, contact your Synergy/DE account manager to order a license block, which enables you to license a specific number of devices. You will receive a token and password (one per license block) that is used to activate each device in the block.
7. Manage licenses and passwords as needed. From the Device Licenses section of the Synergex Resource Center, you can view license block information, modify passwords or add new token/password combinations, transfer licenses from one device to another, deactivate lost or stolen devices, or revoke entire license blocks (e.g., for nonpayment). You can also associate user data with a license block and use that to control application‑ or customer‑specific behavior.

The end users of your device‑licensed application must accept the Synergy/DE Product License Agreement terms and conditions. When you register as a device license subscriber, you will receive further instruction regarding an addition you should make to your application’s license agreement.

How device licensing works

The first time an end user runs your application on a device, the application attempts to activate the license via one of the two methods in step 4 above. The Synergy device runtime then contacts the Synergy device license service, which assigns a unique identifier to the device and activates it by associating it with the license block for those credentials. The device is granted 30 days of authorization.

If the initial activation fails, the device is put into a seven‑day grace period, during which time the user will be able to run the application. However, if the device is not successfully activated by the eighth day, subsequent attempts to run the application will fail. Possible reasons for initial activation to fail include an invalid token/password, a full license block, an expired license block, or a duplicate device description.

Once a device is activated, each attempt to run the application will check the number of days of authorization remaining. If it is within 7 days of authorization expiration (or subscription expiration), the runtime will attempt to synchronize the license information with the server. If this is successful, the device is granted another 30 days of authorization. If the device is expired (i.e., 0 days of authorization remain, or the subscription has expired), and this synchronization fails (e.g., because there is no internet connectivity), the device will be given a 24‑hour grace period during which it must successfully contact the server in order to get another 30 days of authorization. If it is unable to do so within 24 hours, subsequent attempts to run the application will fail.

We recommend that your application be coded to perform regular synchronizations with the device license service at a time when it is likely to have internet connectivity. You won’t want it to synchronize every day, but perhaps you could establish the frequency relative to the expiration date. For example, if it has been 20 or more days since last contact, the application could perform a synchronization. This information can be obtained using GetLicenseInfo.

A device can also be put into “forced expiration,” where the number of authorization days is set to 0. This occurs on the first successful synchronization following either a deactivation of the device or the revoking of a license block via the device license management website.

Deactivating a device

Before transferring a license or uninstalling a device application, we strongly recommend that you first deactivate the device license. You can code a feature in your application that deactivates a device by calling DeviceLicensing.Deactivate. The Deactivate method clears the local license information stored on the device and frees up a slot in the license block.


Since license information is application specific, you will need to deactivate the device for each device‑licensed application installed.

A device also needs to be deactivated if it is lost, stolen, discarded, or rendered inoperable, or if the device owner has left the company and taken the device. In these cases, since the device is no longer accessible, you must either use the device license management website or contact Synergex to deactivate the device. You will need to provide the license block information as well as the unique device description.


We recommend you code a feature in your application that allows you to display the token and device description (using DeviceLicensing.GetLicenseInfo) so you can easily identify devices and manage them.

Transferring a license

If a license needs to be transferred from one device to another (e.g., when upgrading to a newer model), you must first deactivate the device license. See Deactivating a device above. Once a slot is freed up in the license block, the license can be activated on the new device.

Uninstalling your application

On Windows servers, device licensing is per user. On Windows desktops, laptops, and tablets running non‑UWP applications, device licensing is per machine/device. In both cases, local license information is stored in a file. On Windows platforms running UWP applications, device licensing is per application, and local license information is stored in the application sandbox.

Prior to uninstalling a device‑licensed application, you must deactivate the device. This clears the local license information and updates the cloud device license service. (On per‑user platforms, you do not need to do this if you plan to subsequently reinstall the application.) See Deactivating a device above.

Implementing device licensing


Synergex provides code samples that demonstrate recommended callback implementations. For a non‑device implementation of device licensing, see the WPFDeviceLicense.zip sample, available from Synergy CodeExchange in the Resource Center on the Synergex website.

1. Write a Synergy .NET assembly that imports the Synergex.SynergyDE.DeviceLicensing namespace and contains a class that implements the ISynergyDeviceCallback interface. (See Synergex.SynergyDE.DeviceLicensing.ISynergyDeviceCallback for more information and an example.) This class must contain each of the following methods:

The Synergex.SynergyDE.DeviceLicensing namespace that you imported also contains the DeviceLicensing class, which includes several methods that you can use to activate or deactivate a device, request a unique device identifier from the device license service, force license synchronization with the device license service, or retrieve local device license information (such as the license expiration date). Some of these routines must be called at specific times; others can be called at your discretion. See Synergex.SynergyDE.DeviceLicensing.DeviceLicensing for more information.

2. Add the SynergyDeviceLicenseAttribute attribute to your assembly from step 1. The SynergyDeviceLicenseAttribute attribute supports the following property values:

For example,

AppGUID="MyGuid999", Class=^typeof(MyNamespace.myClass))}
3. On Windows servers, desktops, laptops, or tablets, add a call to DeviceLicensing.WaitForLicense at the beginning of your application. This prevents the application user interface from appearing prior to license enforcement. (If you are using an application login, you don’t need to do this because you are already suspending the application from proceeding until successful login.)
4. Compile your Synergy .NET assembly (from step 2) using the “Enable device licensing” option on the Compile page of Project Designer (in Visual Studio).
5. If your main routine is non-Synergy .NET, call Synergex.SynergyDE.SysRoutines.dscrdeviceinit() at the start of your application to ensure that Synergy is licensed immediately, rather than waiting for the first Synergy routine to be invoked (which could be minutes after application launch).

When your application (assembly) starts up, it will automatically load the Synergy device license subsystem, which attempts to initialize and then activate the device by invoking the necessary callbacks. Once the device is activated, the end user can access the application as long as the device license subscription is valid.


To minimize activation of device licenses during debugging and testing for UWP, make sure the “Uninstall and then re-install my package...” option on the Debug page is not selected for the executable's project.


To help troubleshoot device licensing problems, we recommend that you include a feature in your application that calls DeviceLicensing.GetLicenseInfo to obtain local license information. You can then submit the LicenseInfo.DebugInfo value (which is encrypted) to Synergex for assistance.

Once Synergex has received this information, they may direct the user to clear the local license information. Therefore, we recommend that your application also include a feature that calls DeviceLicensing.Deactivate, to simplify this process.