Tag Archives: code

Uniface’s use of Authenticode

In this blog post I discuss how Uniface uses Authenticode for signing Uniface executables on the Windows platform. A word on the merits of signing your executables. Code signing is nothing more than taking an executable and calculating a checksum, attaching that checksum in a cryptographically secure way to the executable. This way any customer can be assured of the integrity of the code they download from Uniface’s download server: it has not been tampered with nor was it altered while in transit. The use of a public-private key certificate from a reputable vendor adds the advantage that you can rest assured the code you downloaded really originated from Uniface.

Designing code signing requires you to take a step back revisiting your existing processes to identify potential issues. Any statements on the integrity of the code can only be satisfied if you manage your code signing keys in a defined way. We have a defined process of managing where keys reside, who has access to them and what people having access can do. Keys reside in a physically secured location, with access being controlled and limited to a small group of people in the company. Only these people can get their hands on the Uniface code signing keys for a limited set of defined purposes. Strict logging is in place so that key usage can be reviewed from audit logs.

The Uniface build factory consists of machines, that take source code from a version control system and run the build scripts to produce signed executables. The code signing is run directly from our makefiles. We use a set of ‘internal’ certificates when building Uniface. Machines that are part of the Uniface build factory have access to the ‘internal’ certificate and physical access to the build machine is limited. Only Windows executables that were produced in an official build can thus be signed using this ‘internal’ certificate. The certificate is only valid within the Uniface development lab. Outside the Uniface development lab a machine with Windows installed would lack the Uniface development lab ‘root’ certificate, which is needed to build a trust chain required to validate executables signed with the ‘internal’ certificate. Once we package a Uniface q-patch, patch, service pack or distribution, we also sign these deliverables. This effectively seals the package and protects its contents from unauthorized modifications.

We also timestamp all files, which means all signed files also carry an official counter signature with a timestamp. Should there be an irregularity, forcing us to withdraw our software, we can do this by revoking our certificate. This comes in two flavours: Either we fully revoke a certificate, or we revoke the certificate from a certain cut off timestamp. When the certificate is fully revoked, all files signed with this certificate become invalid and hence cannot be trusted anymore. If the exact moment in time when the irregularity occurred is known, we can revoke the certificate from this moment in time. This results in all files signed after this moment to become invalid. Files signed before this moment in time remain valid.

When we decide that a package is ready for shipping to our customers, we go through a process of re-signing such a package with our ‘external’ certificate.  This is done as part of the publication process. What we do is check every file in the package to see if it was signed using the Uniface ‘internal’ certificate. If a file was signed with the ‘internal’ certificate, it is resigned using our ‘external’ certificate. This ‘external’ certificate was obtained from a reputable vendor and the public key of the root certificate from that vendor is present in every Windows distribution. Hence using public-private key encryption, your Windows distribution can check that files that we have signed in our Uniface distribution have not been modified since we signed them and that the software is actually from us. So the next time you install Uniface, you can be sure the software is fine.

Uniface 10: What’s happened since the release?

Back in September 2016 we had quite a major event, Uniface 10 was released with the ability to develop and maintain all forms of Uniface applications – Client Server, Web and batch.

Uniface 10

Since the release, and based on lots of feedback from the early adopters, we have continued to actively enhance the IDE with constant incremental improvements. In this blog post, I would like to share with you what these improvements are as well as what we have planned for the near future.

To start, it is probably a good idea to give some high-level topics we have been concentrating on.

Migration

This topic has probably been our primary focus during the continuous updating of v10. We have always had a migration path between Uniface versions automating any updates needed. In version 10 we continue with this concept and as information becomes available, from customers and our own experiences, the migration utilities have been updated to further improve the experience.

Uniface 10: Code migrated from 9 to 10
Uniface 10: Code migrated from 9 to 10
Usability and bug fixing

Performance in large repositories has proven to be an area where we have needed to pay attention and has generated some lively discussions on uniface.info. Although this is an ongoing theme we have already made significant enhancements. The dropdown browse dialogs for the Development Objects (cpt:, ent:, libinc:, etc) will load the information and format the data with considerably less of a delay. Incremental rendering has also been added so that the list becomes available and usable even while extra rows continue to be added. The same techniques and improvements will also be added to the resource browsers in the coming patches.

Uniface 10: Cascading brows dialogs
Uniface 10: Cascading browse dialogs
Embedding the GUI screen painter

Client server development is another area we are enhancing. The first enhancement we are planning and currently working on is embedding the form painter directly into the v10 IDE.

Uniface 10: Embedded form painter taken from a developer's PC
Uniface 10: Embedded form painter taken from a developer’s PC
Runtime enhancements

It is now possible to specify what trigger, accept or quit, will be called when an auto close popup loses focus.

The ability to undeclare a trigger, operation or local proc. This will allow model or previously defined scripts to be excluded from the compile effectively allowing default functionality for a trigger to be re-established.

The ability to call up to a higher-level trigger has been added, this allows such actions as explicitly calling the entity level Detail trigger from the field level detail trigger.

Uniface 10: New popup options
Uniface 10: New popup options

As you can see, we’ve been very busy, and there is a lot more to come.

How to restore default behavior in Uniface 10

In Uniface 9, there are two types of trigger behavior:

  • Implicit or default Uniface behavior;
  • Explicit behavior

The most well-known example of implicit or default behavior is the execute trigger, which displays the component in edit mode, even if you do not declare it. Explicit behavior is all code that a developer writes. This explicit behavior will block default behavior even if you did not intend to. I cannot count the number of times I created an execute trigger and forgot to explicitly add the edit statement.

In Uniface 9, every trigger has its own code container and is validated by the compiler. In a way, all triggers are defined implicitly. The way to restore default behavior is to replace the (inherited) code in the trigger with a semicolon (sometimes followed by a comment). The semicolon breaks inheritance but does not implement any other explicit behavior. The compiler considers it to be empty and will disregard it during compilation. At runtime, Uniface will revert to its default behavior (if it has any).

In Uniface 10, we reduced the number of containers. An entity has a maximum of three containers; one for the declarations; one for the collection operations and one for the occurrence operations (and all other occurrence level modules, such as triggers). Fields, components, and application shells have only two; a Declarations container and a Script container. The Script container is where you store your triggers, operations and entries. There is no way to implicitly define a trigger anymore. Every trigger is either inherited or explicitly declared; in both instances, the trigger loses its default behavior. 

Restoring the default behavior by using a semicolon in the trigger no longer works. During compilation, Uniface 10 will create a trigger that does nothing when executed. It still breaks inheritance but no longer restores the default behavior.


; this trigger breaks inheritance 
; but does not restore the default behavior
; in Uniface 10
trigger detail   
; 
end ; trigger detail

The only real solution to revert back to the default behavior is to convince the compiler to ignore all explicit behavior. For this purpose, we introduced the ‘undeclare’ keyword, which instructs the compiler to skip the compilation of the explicitly defined triggers, thereby restoring the default behavior:


undeclare trigger detail

Triggers can only be undeclared after they have been declared. When a trigger is undeclared before its declaration (or when it does not exist at all) the compiler will ignore the undeclare and issue a warning in the messages tab..


; first declare the trigger 
trigger detail  
  askmess "detail trigger"
end
; then undeclare it
undeclare trigger detail

Undeclaring inherited triggers

A trigger that a component inherits from a modeled entity or field can be undeclared in Script container of the modeled object or in the Script container of corresponding derived object in the component. 

 The Script container of a modeled field contains the following code:


trigger detail
  askmess "detail trigger"
end

The Script container of that same field on a component


undeclare trigger detail

This will result in the removal of the modelled detail trigger and will restore the default behavior (if it has any).

Undeclaring operations and entries

It is also possible to undeclare operations and entries:


operation myOperation
   ; some code
end ; myOperation
undeclare operation myOperation

entry myEntry
  ; some code
end ; myEntry
undeclare entry myEntry

For operations, the same rule applies as for triggers; they can be undeclared in the modeled or the derived object, but it must be done in same code container. For instance, if an operation is declared in the Occurence Script container on the model level it can only be undeclared in the same container on either the model level or the component level.

For entries it works differently. Since entries have a component scope, the entry can be undeclared in every container that is compiled after the last time the entry was declared. This requires a deeper understanding of how the compiler works.

Uniface 10: Code containers, code inheritance and default behavior

One of the many nice, new things about the Uniface 10 Development Environment is the Code Container. Each of your development objects, like components, entities and fields, has its own container that houses all of its triggers, operations and entries, generically called modules.

Uniface 10: Code Containers
Uniface 10: Code Containers

With this new way of organizing code, Uniface 10 provides ProcScript code inheritance in a very clear consistent way; code inheritance is purely on the level of the individual module.

Simply put: a ProcScript module defined at a specific level, overrides any implementation that module might have at a more generic level. Or, from a different perspective: if you do not implement a ProcScript module at a specific level, Uniface will fall back to the implementation of that module at the nearest (inheritance-wise) more generic level.

For triggers, the most generic level is really very generic: it is the built-in default trigger behavior. For most triggers the default behavior is to do nothing, but some triggers do have real default behavior. For example, if you omit an entity’s trigger create at all levels, Uniface still adds an occurrence when the user presses ^ADD_OCC.

The code containers, and the uniform way of code inheritance that comes with them, make Uniface 10 a real pleasure to work with, especially in combination with the Compiled Modules Inspector, which you find at the right-hand side of the Component Editor’s Write Script worksheet. It shows all modules that were compiled into the component, wherever they came from. A simple double-click on any of them moves you right into the code container of the object where that code was defined.

I love it!

Uniface 10: The new procedural declaration of component variables

For Uniface 10 we are constantly reviewing and redefining old concepts, aiming for consistency and reusability while looking for new ways to improve your developing experience and enforce good development practices. This is what the new procedural declaration of component variables is all about.

If you are a developer coming from older Uniface versions you probably are familiar with the ‘Define Component Variable’ form, that allows the creation of variables with component scope and an optional display format. You certainly also know how to declare local variables using the variables block in your triggers and modules. In that case, you might have wondered while accessing the ‘Go To -> Component Variables…‘ menu, selecting the data type from a dropdown list, entering a display format and filling a couple of optional fields… Why can’t I do this from my code, like with local variables?

There are some advantages in the form approach, but the truth is that variables declaration is a fundamental part of coding, as it is the concept of variables scope. It is not only logical but even expected for new developers that variable definitions at component level have component scope. Furthermore, is it a more efficient method of defining and inspect variables. If you think that way, congratulations: You got it! If you are not convinced yet, please keep reading.

In version 10 (10.1.03 and higher) component variables are declared using the ‘variables’ block in the Declarations container of a component. You may declare as many blocks as you want, taking in account that variable redefinitions are not allowed by the compiler. The display format definition takes place -optionally- in the declaration itself, so it looks like this:


variables

DataType {DisplayFormat} VariableName {, VariableName2 ... {, VariableNameN}}

endvariables

The display format is defined using the ‘DIS(<format>)‘ syntax, as it used to be in the ‘Define Component Variable‘ form. You can find extensive documentation about display formats in the Uniface Library. As for the missing fields ‘Description‘ and ‘Comments‘… Well, nothing better than in-code comments to describe our variables.

An actual example of component variables block could be:


variables

string                         vCity, vCountry

string DIS(Mr./Ms. ??????????) vFormattedName         ;- Formatted name for official notifications

date   DIS($NLS(MEDIUM,DATE))  vStartDate, vEndDate   ;- Start/End of contract

float  DIS(9999999P99 US$)     vSalary                ;- Net salary in US dollars

endvariables

Simple, isn’t it? But here is the best part: since component variables are declared procedurally, you can use all the precompiler directives to generate, influence and include component variable declarations. Move your variables block to an include proc to make it reusable. Use the #for directive to quickly generate variables. Make use of definitions to avoid typing complex display formats and ensure consistency between components. Create a snippet library with display formats to quickly insert them into your code.


variables

;- Predefined variable declaration for error handling:

#include MYLIB::ERROR_VARS                 

#for CPTVAR in (NAME,SURNAME,CITY,COUNTRY)

string v<CPTVAR>                      ;- Generate component variables for customer data

#endfor

string <IBAN_FORMAT> vAccount           ;- Predefined printed format for IBAN code (IBAN ???? ???? ???? ???? ????)

endvariables

If you are still hesitant don´t despair: We keep working on great ideas to make code editing faster and easier, as well as providing code and compiled objects information on the editors. But more about that in another blog post…

In the meantime, leave us a comment with your thoughts about the new system! What do you like? What can be improved? How would you make the best use out of it?