воскресенье, 15 сентября 2013 г.

How to protect several binaries using 1 license file

It is not quite common scenario but I’ve been asked several times in the past whether several binaries (EXEs and DLLs) can be protected using 1 license file. For example, your product consists of the several executable files which should share same licensing information. The answer is: yes, it is possible, and it is easy to implement.

Let me show how it can be done.  Suppose our product consist of the 2 separate executable files: FirstUtility.exe and SecondUtility.exe which are presented by 2 different projects in the Visual Studio:



We would like to add license protection to both projects and licensing information should be shared between these 2 projects. Unfortunately we can’t simple share same license file between 2 projects because both executable files are signed and use own assembly information. In this case the license will not pass product name/version/signature validation. But we can achieve our goals using another way:

1. Add new class library to your solution. Name it, for example, SharedLicenseProtection:


2. Add reference to the Manco.Licensing.dll into all projects in your solution.

3. Add reference to the SharedLicenseProtection project into the FirstUtility and SecondUtility projects.

4. Add class which will implement license protection (SharedLicense, for example) to the SharedLicenseProtection project. Left it empty for a while.

5. Build your solution to create SharedLicenseProtection.dll.

6. Run License Manager and import product definition from the SharedLicenseProtection.dll. Pay attention, the protected assembly in the version definition will be SharedLicenseProtection (not the FirstUtility or the SecondUtility):



7. Add license type which corresponds to your license protection requirements. In our sample we will use simple “Unlock Key” licensing schema extended with “Product Edition” rule to implement an ability to turn on/off first and second utility separately using product feature list (see instructions in the “Manage application’s feature list using Product Edition” topic). We change format of the “Unlock Key” to support feature list as well (see screenshot above).

8. Create custom control to edit feature list (see instructions in the “Manage application’s feature list using Product Edition” topic).

9. Change the SharedLicense class to implement ILicenseKeyProvider interface (see details in the product documentation, topic “Quick start using ‘Unlock Key’ licensing schema):



10. Create evaluation license file and add it to the SharedLicenseProtection project (see details in the product documentation, topic “Quick start using ‘Unlock Key’ licensing schema).

11. The SharedLicense class should load license file and instantiate license properties. As usual we do it in the class constructor. In this scenario we want to validate integrity of the calling assembly. We will pass assembly and public key information as parameters of the class constructor. We also need access to the license object outside of the SharedLicense class. So we add License property to it. Finally SharedLicense class could looks like the following:



12. Now we can use SharedLicense class in the First and Second utilities. The scenario is absolutely similar to the standard approach. The difference is that instead of instantiating of the Manco.Licensing.License object we create object of the SharedLicense type and use its License property.

You can find sample solution which implements this approach on our official site at the http://www.mancosoftware.com/licensing/download.htm

воскресенье, 28 июля 2013 г.

Protect Windows Store Application using Unlock Key with Activation licensing schema

Version 8.0 of the Manco .NET Licensing System supports license protection of the .NET Windows Store Applications. It provides separate protection library which can be used with this kind of applications.

I suppose that you have read section “Online product activation” in our product documentation already. So I describe only things are specific for the Windows Store Application in this article.

First of all you should keep in mind that Windows Store Application has not access to the traditional protected storage locations are used by our system in .NET Framework applications: Windows Registry and IsolatedStorage. So protection library uses another approach in this case. To make it possible for License Manager to clear protected storage you should inform it that this is Windows Store Application:


Next, you should use special edition of the protection library designed for the Windows Store Applications. You can find it here: in the InstallationPath/DLL/WinStore/Manco.Licensing.dll where InstallationPath depends on your OS:
  1. For 32-bits OS it is “C:\Program Files\Manco Software\Manco .NET Licensing System”.
  2. For 64-bits OS it is “C:\Program Files (x86)\Manco Software\Manco .NET Licensing System”.

The next difference is the asynchronous nature of the Windows Store Application. To call Activation Web Service you should use asynchronous calls provided with AwsHelper class. For example, to activate license you can use following method:


C#

private async void ActivateLicense(object sender, RoutedEventArgs e)
{
       // If "Unlock Key" has been entered
       if (this.UnlockKey.Trim() != string.Empty)
       {
             string message = null;

             // Pass "Unlock Key" to the license object
             this.license.UnlockKey = this.UnlockKey.Trim();

             AwsHelper helper = new AwsHelper(
                    this.license,
                    MainPage.ActivationServiceUrl);

             try
             {
                    string activationKey = await helper.ActivateProductGetKeyAsync(false);

                    if (!string.IsNullOrEmpty(activationKey))
                    {
                           // AWS has been called
                           m_bAWSCalled = true;
                           txtActivationKey.Text = activationKey;
                           await MainPage.ShowMessage(
                                  "Activation Key has been succesfully"
                                  + " generated and passed to the text box."
                                  + " Click OK to continue.");
                    }
             }
             catch (Exception exc)
             {
                    message = MainPage.ProcessException(exc);
             }

             if (!string.IsNullOrEmpty(message))
             {
                    await MainPage.ShowMessage(message);
             }
       }
       else
       {
             await MainPage.ShowMessage("Enter Unlock Key to be able activate product");
       }
}

VB.NET
Private Async Sub ActivateLicense(sender As Object, e As RoutedEventArgs)
       ' If "Unlock Key" has been entered
       If Me.UnlockKey.Trim() <> String.Empty Then
             Dim message As String = Nothing

             ' Pass "Unlock Key" to the license object
             Me.license.UnlockKey = Me.UnlockKey.Trim()

             Dim helper As AwsHelper = New AwsHelper( _
                      Me.license, _
                      MainPage.ActivationServiceUrl)

             Try
                    Dim activationKey As String = Await helper.ActivateProductGetKeyAsync(False)

                    If Not String.IsNullOrEmpty(activationKey) Then
                           ' AWS has been called
                           m_bAWSCalled = True
                           txtActivationKey.Text = activationKey
                           Await MainPage.ShowMessage( _
                                  "Activation Key has been succesfully" _
                                  & " generated and passed to the text box." _
                                  & " Click OK to continue.")
                    End If
             Catch exc As Exception
                    message = MainPage.ProcessException(exc)
             End Try

             If Not String.IsNullOrEmpty(message) Then
                    Await MainPage.ShowMessage(message)
             End If
       Else
             Await MainPage.ShowMessage("Enter Unlock Key to be able activate product")
       End If
End Sub


You can find sample solution which demonstrates protection of the Windows 8 Store Application on our official site at http://www.mancosoftware.com/licensing/download.htm


 

среда, 3 июля 2013 г.

Version 2.0 of the Manco Shapefile Editor has been released

Manco Shapefile Editor version 2.0 is available now. You can get 30-days trial version at the http://www.mancosoftware.com/ShapeFileEditor/download.htm

List of the most significant changes made in the new version:

  1. KML export/import.
  2. Mixed layers. Layers with the mixed shape types (e.g. Points, lines, polygons in the same layer). Mixed layers can be split. And also can be saved not only as a KML but also as a Shape file by auto-splitting.
  3. Creating, editing and saving of the complex shapes.
  4. Opening background pictures in given coordinates.
  5. Creating shape layers from the background layers in given coordinates.
  6. Shape rotation.
  7. Shape resize.
  8. Functional toolbar.
  9. Rulers.

понедельник, 17 июня 2013 г.

Version 8.0 of the Manco .NET Licensing System has been released

Manco .NET Licensing System version 8.0 is available now. You can get 15-days trial version at the http://www.mancosoftware.com/licensing/download.htm

List of the most significant changes made in the new version:

  1. Created protection library for .NET Windows 8 Store Applications.
  2. Simplified implementation of the license protection in the customer's applications. Eliminated using of the LicenseProvider attribute and LicenseManager.Validate call in the protected class. The ILicenseKeyProvider can be implemented in any class in the project. The instance of the License class can be created as simple as “License license = new License(keyProvider);”. 
  3. Changed license file signature method. Pay attention, the new protection library can’t use license files created by License Manager (or License Shop) version 7.1 and early. But License Manager version 8.0 can creates license files for new protection library as well as for the early versions.
  4. Protection libraries for the medium trust environment are included into the distribution.
  5. New web-method added to the Activation Web Service. This method allows send requests for license activation/validation and gets responses in the encrypted form. For additional security the AWS response data is stamped with Date and Time and signed. Currently following operations are supported: product activation, product deactivation, get customer information, check license existence and online license validation.
  6. New class AwsHelper has been added to the protection library. It simplifies communication of your application with Activation Web Service using encrypted interface.  This class provides methods for the synchronous calls as well as for the asynchronous calls. The asynchronous calls are implemented using Task Framework which makes possible using of the async/await style programming in .NET Framework 4.5 applications.
  7. Added ability to specify which custom values should be copied when upgrade license to the new version of the product.  For example, "CryptoKey" shouldn't be copied, because in the most cases it is version (or license type) specific.
  8. License Manager and Protected Storage Cleaner are able to clear protected storage for the Windows 8 Store Applications.
  9. Added ability to see all purchases for the customer.
  10. Added ability to see all activations for the single purchase.
  11. Added ability to specify which control should be used to edit custom value.

воскресенье, 9 июня 2013 г.

Version 4.5 of the Manco .NET Obfuscator has been released

Version 4.5 of the Manco .NET Obfuscator has been released. New version supports obfuscation of the .NET Windows Store applications (as well as .NET Framework 2.0, 3.0, 3.5, 4.0, 4.5 and .NET Compact Framework 2.0 and 3.5).

суббота, 5 января 2013 г.

Using of the custom profile to activate license against e-Mail address


Often our customers ask whether it is possible to use e-Mail address instead of PC hardware information for license activation. I would say that from my point of view using of the e-Mail address isn’t as secure as using of the hardware profile, but answer is “yes, you can use e-Mail address for license activation”. In this post I’ll describe how you can use “Custom Profile” feature for these purposes.
I suppose you’ve read following topics in the Manco .NET Licensing System documentation:

1.       Quick start using “Unlock Key” licensing schema.
2.       Online product activation.
3.       Include custom information to the PC profile.
Product documentation is a part of the installation package (you can get it here: http://www.mancosoftware.com/licensing/download.htm). After installation you can find product documentation in the Windows Start menu at the “All Programs->Manco Software->Licensing System”, file name is “Manco .NET Licensing System – Documentation.pdf”. It contains about 220 pages with different aspects of using of our system.

Using “Custom Profile” feature you can add custom information to the PC profile, or even completely replace it with your own value. To do it you have to use CustomProfileMode and CustomProfile properties of the license object. The CustomProfileMode property sets value which indicates how the custom profile will be combined with system information. It can have following values:

  1. None – indicates that custom profile will not be used.Combine – indicates that custom profile will be added to the hardware information.
  2. Combine – indicates that custom profile will be added to the hardware information.
  3. Override – indicates that custom profile will override hardware information.
 
The CustomProfile property sets value which will be used as custom profile.
Since we would like to use customer’s e-Mail address for license activation we should override PC system information with e-Mail address. So we should set CustomProfileMode to the “Override” and put e-Mail address to the CustomProfile. We also should provide an application with ability to store entered e-Mail address. We can use license custom value for these purposes.

Here are the changes we should make in the basic code of the “Unlock Key with Activation” licensing schema to be able to activate license against e-Mail address:

[C#]
public MainWindow()
{
       InitializeComponent();
 
       // Instantiate license object and assign assemblies for validation.
       this.license = (Manco.Licensing.License)LicenseManager.Validate(
             typeof(MainWindow), this);
       this.license.LicensedAssembly = typeof(MainWindow).Assembly;
 
       // We will override PC profile with custom value.
       this.license.CustomProfileMode = CustomProfileMode.Override;
 
       // Read e-Mail address from the custom license value
       // and use it as custom PC profile.
       this.license.CustomProfile = this.license.GetCustomValue("EMailAddress");
 
       this.licenseProperties = this.license.GetLicenseProperties();
       this.licenseState = this.license.GetLicenseState(true);
}
 
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
       // Check if the current license is evaluation license or not valid
       if (this.licenseState.IsEvaluation || !this.licenseState.IsValid)
       {
             // This is evaluation or not valid license,
             // so we should show evaluation dialog
 
             // Clear saved keys to allow enter all keys from the scratch.
             license.ClearUnlockKeys();
 
             EvaluationWindow loForm = new EvaluationWindow(license);
             loForm.Owner = this;
             if (loForm.ShowDialog() == true
                    && loForm.UnlockKey.Trim() != string.Empty
                    && loForm.ActivationKey.Trim() != string.Empty)
             {
                    // Check whether license REQUIRE the calling of the AWS
                    // and it has been called from the license form.
                    if (loForm.IsAwsCalled || !this.licenseProperties.DoForceValidation)
                    {
                           // License information have been entered.
                           // Pass it to the license object for the
                           // following validation.
                           license.UnlockKey = loForm.UnlockKey;
                           license.ActivationKey = loForm.ActivationKey;
 
                           // Save entered e-Mail address for the future using.
                           this.license.SetCustomValue("EMailAddress",
                                  loForm.EMailAddress);
                    }
                    else
                    {
                           MessageBox.Show("You must click 'Activate' button on the valuation form"
                                 + "to activate your copy of the product on this PC.");
                    }

             }
             else if (this.licenseState.IsEvaluationExpired)
             {
                    // The evaluation license has been expired and
                    // no license information have been entered,
                    // so we should close application.
                    Application.Current.Shutdown();
                    return;
             }
       }
 
       // ...
}
 
private void ActivateLicense(object sender, RoutedEventArgs e)
{
       // If "Unlock Key" has been entered
       if (!string.IsNullOrEmpty(this.UnlockKey)
             && !string.IsNullOrEmpty(this.EMailAddress))
       {
             // Pass "Unlock Key" to the license object
             this.license.UnlockKey = this.UnlockKey;
 
             // Pass e-Mail address as custom profile.
             this.license.CustomProfile = this.EMailAddress;
 
             // Get instance of the Activation Service
             TimeSpan loAWSTimeout = TimeSpan.FromSeconds(120);
             ActivationWebService.ActivationServiceSoapClient loAWSClient =
                    AwsHelper.InitializeAwsClient(
                    "http://localhost/ActivationService/ActivationService.asmx",
                    loAWSTimeout,
                    loAWSTimeout);
             try
             {
                    bool isActivated;
 
                    if (loAWSClient.LicenseExists(this.license.ProductID, out isActivated))
                    {
                           // Get product ID from the license and try to activate it
                           // Instruct AWS do NOT send copy of the key to the
                           // customer's e-Mail
                           string lsActivationKey =
                                  loAWSClient.ActivateProductGetKey(
this.license.ProductID, false);
                           if (lsActivationKey != null)
                           {
                                  // AWS has been called
                                  m_bAWSCalled = true;
                                  txtActivationKey.Text = lsActivationKey;
                                  MessageBox.Show("Activation Key has been succesfully"
                                        + " generated and passed to the text box."
                                        + " Click OK to continue.");
                           }
                    }
             }
             catch (SoapException exc)
             {
                    if (exc.Message.Contains("Manco.Licensing.ActivationWebService.Exceptions.AllowedActivationsExceededException"))
                    {
                           // Process AllowedActivationsExceededException
                           MessageBox.Show("Number of the allowed activations exceeded.");
                    }
                    else
                    {
                           MessageBox.Show("Exception during activation:\n" + exc.ToString));
                    }
             }
             catch (Exception exc)
             {
                    MessageBox.Show("Exception during activation:\n" + exc.ToString());
             }
       }
       else
       {
             MessageBox.Show("Enter Unlock Key and e-Mail address to be able activate product");
       }
}
 

[VB.NET]
Public Sub New()
       InitializeComponent()
 
       ' Instantiate license object and assign assemblies for validation.
       Me.license = DirectCast(LicenseManager.Validate(GetType(MainWindow), Me), Manco.Licensing.License)
       Me.license.LicensedAssembly = GetType(MainWindow).Assembly

       ' We will override PC profile with custom value.
       Me.license.CustomProfileMode = CustomProfileMode.Override

       ' Read e-Mail address from the custom license value
       ' and use it as custom PC profile.
       Me.license.CustomProfile = Me.license.GetCustomValue("EMailAddress")
 
       Me.licenseProperties = Me.license.GetLicenseProperties()
       Me.licenseState = Me.license.GetLicenseState(True)
End Sub
 
Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs)
       ' Check if the current license is evaluation license or not valid
       If Me.licenseState.IsEvaluation OrElse Not Me.licenseState.IsValid Then
             ' This is evaluation or not valid license,
             ' so we should show evaluation dialog
 
             ' Clear saved keys to allow enter all keys from the scratch.
             license.ClearUnlockKeys()
 
             Dim loForm As New EvaluationWindow(license)
             loForm.Owner = Me
             If loForm.ShowDialog() = True _
                    AndAlso loForm.UnlockKey.Trim() <> String.Empty _
                    AndAlso loForm.ActivationKey.Trim() <> String.Empty Then
                    ' Check whether license REQUIRE the calling of the AWS
                    ' and it has been called from the license form.
                    If loForm.IsAwsCalled _
                     OrElse Not Me.licenseProperties.DoForceValidation Then
                           ' License information have been entered.
                           ' Pass it to the license object for the
                           ' following validation.
                           license.UnlockKey = loForm.UnlockKey
                           license.ActivationKey = loForm.ActivationKey
 
                           ' Save entered e-Mail address for the future using.
                           Me.license.SetCustomValue("EMailAddress", loForm.EMailAddress)
                    Else
                           MessageBox.Show("You must click 'Activate' button on the evaluation form" _
                                  & "to activate your copy of the product on this PC.")
                    End If
             ElseIf Me.licenseState.IsEvaluationExpired Then
                    ' The evaluation license has been expired and
                    ' no license information have been entered,
                    ' so we should close application.
                    Application.Current.Shutdown()
                    Return
             End If
       End If
 
       ' ...
End Sub

Private Sub ActivateLicense(sender As Object, e As RoutedEventArgs)
       ' If "Unlock Key" has been entered
       If Not String.IsNullOrEmpty(Me.UnlockKey) _
              AndAlso Not String.IsNullOrEmpty(Me.EMailAddress) Then
             ' Pass "Unlock Key" to the license object
             Me.license.UnlockKey = Me.UnlockKey
 
             ' Pass e-Mail address as custom profile.
             Me.license.CustomProfile = Me.EMailAddress
 
             ' Get instance of the Activation Service
             Dim loAWSTimeout As TimeSpan = TimeSpan.FromSeconds(120)
             Dim loAWSClient As ActivationWebService.ActivationServiceSoapClient = _
                    AwsHelper.InitializeAwsClient( _
                    "http://localhost/ActivationService/ActivationService.asmx", _
                    loAWSTimeout, _
                    loAWSTimeout)
             Try
                    Dim isActivated As Boolean
                    If loAWSClient.LicenseExists(Me.license.ProductID, isActivated) Then
                           ' Get product ID from the license and try to activate it
                           ' Instruct AWS do NOT send copy of the key to the
                           ' customer's e-Mail
                           Dim lsActivationKey As String = loAWSClient.ActivateProductGetKey(Me.license.ProductID, False)
                           If lsActivationKey IsNot Nothing Then
                                  ' AWS has been called
                                  m_bAWSCalled = True
                                  txtActivationKey.Text = lsActivationKey
                                  MessageBox.Show("Activation Key has been succesfully" _
                                  & " generated and passed to the text box." _
                                  & " Click OK to continue.")
                           End If
                    End If
             Catch exc As SoapException
                    If exc.Message.Contains("Manco.Licensing.ActivationWebService.Exceptions.AllowedActivationsExceededException") Then
                           ' Process AllowedActivationsExceededException
                           MessageBox.Show("Number of the allowed activations exceeded.")
                    Else
                           MessageBox.Show("Exception during activation:" _
                                  & vbLf & exc.ToString())
                    End If
             Catch exc As Exception
                    MessageBox.Show("Exception during activation:" _
                                  & vbLf & exc.ToString())
             End Try
       Else
             MessageBox.Show("Enter Unlock Key and e-Mail address to be able activate product")
       End If
End Sub
 
You can find sample solution which demonstrates how the custom profile can be used to activate license against e-Mail address here: http://www.mancosoftware.com/licensing/download.htm