is an extension for the Xheo|Licensing offered by XHEO (www.xheo.com). EverLicenseX expands the options available to you when protecting your .Net application components using Xheo|Licensing using "UnlockBySerial" licenses. There are some limitations regarding the use of the UnlockBySerial licensing approach which can impact those who are creating controls which they intend to sell to other developers who will consume them in web applications or products that they in turn intend to sell or distribute:EverLicenseX
EverLicenseX addresses these and other issues by providing a custom Limit which, if no serial number has yet been entered, invokes a form (which can be customized by your customer) to prompt for serial and (optionally) registration info. This Limit is different from the Xheo registration limit in that the serial is then persisted to either a registry key or a serial number file (you choose which). Your customer can then ensure that the key or file is installed on their customers' machines via their installer. The serial is encrypted before being persisted to the target location, and you can specify that the key used in this encryption process be tied to the machine or just the assembly, providing the ability for the persisted serial to be machine-specific, or not
For Web Application, where no pop-up serial prompt is possible, you can allow your customers to simply create an AppSetting key/value containing a valid serial number.
A custom LicenseHelper responds to requests from Xheo|Licensing and retrieves the serial from whichever persistence mechanism you have chosen.
The values you can user for EverWare.Licensing.KeyUniqueness are:
- MACHINE - When a serial number is entered, it is tied to the machine on which it is entered as it is persisted to the chosen location. Copying the registry entry or .ser file thus created to another machine will result in an invalid serial number and a valid serial number will have to be re-entered on that target machine.
- ASSEMBLY - When a serial number is entered, it is tied to the assembly being protected as it is persisted to the chosen location. Copying the registry entry or .ser file thus created to another machine will not require re-unlocking on that machine. Considerations: The CONFIG persistence option is intended mainly to support the ability to enable a control or assembly used in an ASP.Net application. Since interactive prompting at runtime is not an option, another option for retrieving a serial number is needed.
- COMPANY - When a serial number is entered, it is tied to the company name specified by the AssemblyCompany attribute of the assembly being protected. Copying the registry entry or .ser file thus created to another machine will not require re-unlocking on that machine. Considerations: The CONFIG persistence option is intended mainly to support the ability to enable a control or assembly used in an ASP.Net application. Since interactive prompting at runtime is not an option, another option for retrieving a serial number is needed.
The values you can use for EverWare.Licensing.KeyLocation are:
- REGISTRY - Licensing looks for serials in the registry and persists them there, if entered. The location of the registry entry will depend on whether your the KeyUniqueness setting is MACHINE, ASSEMBLY, or COMPANY. If it is MACHINE or ASSEMBLY, the serials will be stored under the HKLM\Software\<ASSEMBLYCOMPANY>\<ASSEMBLYPRODUCT> key. If COMPANY KeyUniqueness is specified, the serials will be stored under the HKLM\Software\<ASSEMBLYCOMPANY> key. <ASSEMBLYCOMPANY> and <ASSEMBLYPRODUCT> are obtained from those attributes of the Assembly containing your licensed class (usually specified in the AssemblyInfo.cs file). If they are not defined for the Assembly, "EverWare" and the Assembly short name will be used, respectively. The name of the registry entry will reflect the assembly name and version. If COMPANY KeyUniqueness is specified, it will be suffixed with the company name.
- FILE - Licensing looks for serials in a .ser file. The name and location of the .ser file will depend on whether the KeyUniqueness setting is MACHINE, ASSEMBLY, or COMPANY. If it is MACHINE or ASSEMBLY, the file will be created with the name <EXECUTABLENAME>.ser when a serial number is entered, and it will be located in the same directory as the executable. Upon subsequent executions, EverwareLicenseHelper will in the same directory for that file. If COMPANY KeyUniqueness is specified, when a serial number is entered, it will be stored in the Common Program Files directory (usually C:\Program Files\Common File) under the "EverWare Shared" directory, and it will be named "everware_rt.ser". On subsequent executions, EverwareLicenseHelper will look for a file with that name, first in the "<Common Program Files>\EverWare Solutions" directory then, if it is not found there, in the current executable directory. Once the file is created in the common directory, it can be left there, or it can be bundled into the executable directory for redistribution purposes. The .ser file simply contains a serialized Hashtable of encrypted serials, one for each assembly licensed using the EverwareUnlockBySerialLimit.
- CONFIG - Licensing looks in the appSettings in the .config file(s). They must be manually entered there to be persisted. The license is expected to be in clear text. The name of the value, hashtable key, or appSetting where the serial is persisted/expected for the registry, serialized file, or config options respectively, is <SHORTASSEMBLYNAME>_<VERSION>. You will therefore want to be sure to assign a fixed version number to your assembly.
- FILE_OR_CONFIG - Licensing first looks for serials in the <EXECUTABLENAME>.ser file, then looks in the appSettings in the .config file(s). They are persisted to the registry, if entered.
- REGISTRY_OR_CONFIG - Licensing first looks in the registry, then looks in the appSettings in the .config file(s). They are persisted to the registry, if entered. FILE - Licensing looks for serials in the <EXECUTABLENAME>.ser file and persists them there, if entered.
Recapping the effects of the KeyUniqueness attribute:
MACHINE uniqueness ties the persisted serial number to a specific machine. Every time your assembly that is licensed with the EverwareUnlockBySerialLimit is invoked for the first time on a new machine, the user will be prompted for a serial.
ASSEMBLY uniqueness ties the serial to a specific assembly. Every time your assembly that is licensed with the EverwareUnlockBySerialLimit is invoked for the first time by a new assembly, the user will be prompted for a serial. The persisted serial (which will be in the registry or the <EXECUTABLENAME>.ser, depending on the KeyLocation attribute) can then be "packaged" with the consuming assembly for distribution without requiring subsequent serial entry.
COMPANY uniqueness ties the serial to a specific company name. Developers using your assembly in their applications can use it from any of their assemblies, and will only be prompted the first time for a serial number, as long as they sign all consuming assemblies with the same company name.
With respect to the KeyLocation attribute:
CONFIG mode instructs the helper EverwareLicenseHelper to look for the serial in the web app's .config file. The user simply creates an appsetting in their .config file, with the name <SHORTASSEMBLYNAME>_<VERSION>, and sets its value to the serial number assigned to them. Obviously, this doesn't do much to "hide" the serial number assigned to them, so it isn't a great option when your customer is building web applications or assemblies which they in turn intend to redistribute, since the serial gets distributed in clear-text.
So, if you expect that your control will be used by people building applications which they in turn will redistribute, you will want to use the REGISTRY or FILE options. In both cases, serial numbers entered by the consumer of your assembly will be stored in an encrypted form for purposes of obfuscation. This prevents users of an app developed by the person using your control from easily extracting the serial, using your assembly in your own app, and distributing the extracted serial as they please. (Note, however, that serials are encrypted using a symmetric algorithm, so it is not as safe as with a public/private key algorithm.)
The choice of whether to use REGISTRY or FILE is up to you. REGISTRY is probably a better choice if you use a KeyUniqueness of ASSEMBLY, since it obfuscates the key location better. With FILE, your assembly could be used as long as the .ser file resulting from unlocking it on a single machine is distributed with it. MACHINE is obviously a more secure choice for KeyUniqueness, but in the case where the developer using your protected assembly wants to redistribute their resulting work, without their users being prompted to unlock your assembly, it may be less desirable. One option in that case would be to go ahead and use MACHINE uniqueness, but educate the developer consuming your assembly in how to create a custom RegistrationForm (see below), which could include their own branding or get a serial number in some other way.
If you intend to allow customers who buy your control or assembly to use it over and over again in applications they create, and you don't want them to be prompted for a serial number every time that use it in a new assembly, you probably want to use COMPANY uniqueness. Then, as long as your customer is signing all of their assemblies with the same company name, they will only be prompted for a serial number the first time.
The information supplied in the Xheo.Licensing.LicenseHelp attribute is important because if Xheo encounters an error loading the license file, or can't find one, it calls GetSupportInfo() on the LicenseHelper. That method retrieves support info from the Xheo.Licensing.LicenseHelp and returns it in the SupportInfo object Xheo is expecting. Xheo then includes that information in the exception or pop-up window it displays to the user.
Suppose you create an assembly which provides a custom control, "SuperWidget", that you intend to market to the development community through your company, "Widgets, Inc." You want to require that a developer who purchases your control is required to register the control and unlock it with a serial number prior to developing their application. You therefore include a EverwareUnlockBySerialLimit and set the caption property to say something about registering their copy of SuperWidget with Widgets, Inc.
Now, you also want to allow your customers to purchase redistributable rights for the control, so they can create applications which they in turn will market, but you still want to track usage of your control, even if is by your customers' customer. Your customer probably doesn't want your branding to pop up, so you educate them in how to create a custom registration form, and you contractually obligate them to ensure that registration information will still be collected or posted to your server. They then build a custom registration form that displays their own branding, but posts to your server - or perhaps it posts to their server, and they provide you with quarterly reporting, or whatever.
Custom registration forms allow you, or developers writing applications that consume your control, to create a custom form which is displayed when Everware licensing prompts for serial number & registration info. In order to create and enable a custom registration form the developer:
- Creates a new Form which extends the BaseRegistrationForm.
- Implements the abstract propterty accessors defined by BaseRegistrationForm:
public abstract string SerialNumber {get;}
public abstract string CaptionText {set;}
public abstract string LabelText {set;}
public abstract string RegisterButtonText {set;}
public abstract string LaterButtonText {set;}
public abstract string FirstName {get;}
public abstract string LastName {get;}
public abstract string Organization {get;}
public abstract string Address {get;}
public abstract string City {get;}
public abstract string State {get;}
public abstract string Country {get;}
public abstract string Zip {get;}
public abstract string PhoneNumber {get;}
public abstract string Email {get;}
public abstract bool DetailsToggleAvailable {set;}
public abstract bool IsMandatory {set;}
public abstract System.Drawing.Image LogoBitmap {set;}
public abstract bool ShowDetails {get; set;}
- Ensure that the form returns DialogResult.OK if the user enters serial/registration info, and that the serial number and other info entered by the end-user is available via the accessors.
- Ensure that the registery values "CustomRegistrationFormAssembly" and "CustomRegistrationFormClass" are created under the "HKLM/SOFTWARE/EverWare Solutions/Licensing/<SHORTASSEMBLYNAME>/" key and define the custom form's assembly name and class name, respectively. At license validation time, Xheo will request a serial number from EverwareLicenseHelper. if a valid serial is not returned, the EverwareUnlockBySerial limit will be invoke (assuming you've included it in the the license file embedded in your assembly), which will examine the above registry entries, construct the indicated Form class, set the above properties, display the form via ShowDialog(), read the form's properties upon return of control, and finally, persist the returned serial and (depending on the License settings) post the registration info.
Note that a developer creating a custom registration form could have that form behave however they want, as long as it returns a serial number. For example, they could take the serial number entered and persist it in clear text. In a commercial situation or security-conscious situation, some consideration should therefore be given to enforcing policies, contractual or otherwise, on developers creating custom registration forms.