locked
Application Licensing RRS feed

  • Question

  • User325035487 posted

    *The application would be an intranet application with probably no access to intranet. So I couldnt call in a check to an external licensing server. I want to put a dll file in the bin folder which is compiled for every client. Or a similar set up which is not easily crackable.

    I am trying to check in the Application_Start of global.asax whether my application is licensed for that server. I am not used with the desktop version if C#. I tried to read up and find this in stackoverflow - http://stackoverflow.com/questions/3624149/license-for-c-sharp-desktop-application

    Edit: I abandoned the code above, Now have a working solution which can generate and check license. Only pending issues are

    1. how to ensure the end user server admin doesn't edit my global.asax file to remove the license check.
    2. how to exit the application if the license is not valid and show a simple message "No Valid License Found" or something.

    Please see below that I have working code which I tested in a live product using a page called licensecheck.cshtml to check if license is valid and display error message as string if invalid. How to use this concept in Application Start event to exit the application.

    Saturday, August 8, 2015 11:42 AM

Answers

  • User325035487 posted
        //License Validation
        var path = Server.MapPath("~/App_Data/Backup/License.lic");
        var keypath = Server.MapPath("~/App_Data/Backup/key.txt");
        string currentdomain = Request.ServerVariables["LOCAL_ADDR"];
        string licensexml = "";
        string erromessage = "";
        string domainip = "";
        if (File.Exists(path) && File.Exists(keypath))
        {
            licensexml = File.ReadAllText(path, System.Text.Encoding.UTF8);
            var license = License.Load(licensexml);
            string publicKey = File.ReadAllText(keypath, System.Text.Encoding.UTF8);
            var validationFailures = license.Validate()
                                            .ExpirationDate()
                                                .When(lic => lic.Type == LicenseType.Trial)
                                            .And()
                                            .Signature(publicKey)
                                         .AssertValidLicense();
            int i = 1;
            //Read Data
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(licensexml);
            XmlNode node = xmlDoc.SelectSingleNode("/License/ProductFeatures/Feature[@name='Domain IP']");
            
            domainip = node.InnerText;
            foreach (var failure in validationFailures)
            {
                erromessage = failure.GetType().Name + ": " + failure.Message + " - " + failure.HowToResolve;
                <p> @i - @erromessage</p>
                i++;
            }
            if (erromessage == "")
            {
                <p>License Valid on Domain: @domainip - Currentdomain: @currentdomain</p>
            }
        }
        else
        {
            HttpRuntime.UnloadAppDomain();
        }
        if (erromessage != "" || licensexml == "" || domainip != currentdomain)
        {
            HttpRuntime.UnloadAppDomain();
        }

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, August 10, 2015 11:43 AM

All replies

  • User325035487 posted

    I am disappointed with this.. Any ways I abandoned the above script as I found a superb open source library for license management. I haven't solved all the issues yet. But for those of you who is interested, here we go.

    I humbly request Mr. Mike to consider putting up an article on the topic using this library to make life easier for beginners like me.

    First install this library - https://nuget.org/packages/Portable.Licensing

    Or from Packet Manager Console

    PM> Install-Package Portable.Licensing

    Set up an intranet application which will help you generate license for your customers. create a file CreateLicense.cshtml

    @using Portable.Licensing;
    @{
    var passPhrase = "Jayakrishnan.Jayachandran.Nair.1983";
    var keyGenerator = Portable.Licensing.Security.Cryptography.KeyGenerator.Create();
    var keyPair = keyGenerator.GenerateKeyPair();
    var privateKey = keyPair.ToEncryptedPrivateKeyString(passPhrase);
    var publicKey = keyPair.ToPublicKeyString();
    
    var license = License.New()
    .WithUniqueIdentifier(Guid.NewGuid())
    .As(LicenseType.Trial)
    .ExpiresAt(DateTime.Now.AddDays(30))
    .WithMaximumUtilization(5)
    .WithProductFeatures(new Dictionary<string, string>
    {
    {"Sales Module", "yes"},
    {"Purchase Module", "yes"},
    {"Maximum Transactions", "20000"}
    })
    .LicensedTo("John Doe", "john.doe@yourmail.here")
    .CreateAndSignWithPrivateKey(privateKey, passPhrase);
    string file = Server.MapPath("~/App_Data/License/") + "License.lic";
    File.WriteAllText(file, license.ToString(), System.Text.Encoding.UTF8);
    }
    1. You can then copy the generated License.lic file to the App_Data folder in your customers server
    2. Save the publicKey generated above and the private key to seperate columns in your License Manager Server for future verification.
    3. Save the publickey generated above in a text file in App_data folder of your customer and call it maybe key.txt

    Then I created a licensecheck.cshtml and in it I am doing this

    @using Portable.Licensing;
    @using Portable.Licensing.Validation;
    
    //License Validation
    var licpath = Server.MapPath("~/App_Data/License.lic");
    var keypath = Server.MapPath("~/App_Data/key.txt");
    string licensexml = File.ReadAllText(licpath, System.Text.Encoding.UTF8);
    var license = License.Load(licensexml);
    string publicKey = File.ReadAllText(keypath, System.Text.Encoding.UTF8);;
    var validationFailures = license.Validate()
    .ExpirationDate()
    .When(lic => lic.Type == LicenseType.Trial)
    .And()
    .Signature(publicKey)
    .AssertValidLicense();
    int i = 1;
    foreach (var failure in validationFailures) {
    
    string erromessage = failure.GetType().Name + ": " + failure.Message + " - " + failure.HowToResolve;
    <p> @i - @erromessage</p>
    i++;
    }
    

    Actually I am stuck at this place now. Just need some help from here.

    How can I like exit the application if there is any error message. I put the previous code block in a licensecheck.cshtml in the app and after following all previous steps it works wonderfully. Whenever I tried to manipulate the license.lic file using a text editor it gives me error message.

    I hope some one can help me bridge the final gap. The above library is working so perfectly for my need. Just need the logic to exit the application. And show a message in front end saying License not valid or something.

    Please help me to exit the application using the application_start even and above code.

    <%@ Import Namespace="Portable.Licensing" %>
    <%@ Import Namespace="Portable.Licensing.Validation" %>
    void Application_Start(object sender, EventArgs e)
    {
    // Code that runs on application startup
    var path = Server.MapPath("~/App_Data/Backup/License.lic");
    string licensexml = File.ReadAllText(path, System.Text.Encoding.UTF8);
    var license = License.Load(licensexml);
    string publicKey = "MIIBKjCB4wYHKoZIzj0CATCB1wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEIQNrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClgIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABFjISTS5nQeiWWtd/Wnq/9Hl+NW8OfzsHkU0xe68rrX9cSnHAQKA5+V8n22g4vjCo4qggNUPBXUzoqdDVtjFILw=";
    var validationFailures = license.Validate()
    .ExpirationDate()
    .When(lic => lic.Type == LicenseType.Trial)
    .And()
    .Signature(publicKey)
    .AssertValidLicense();
    foreach (var failure in validationFailures)
    {
    string erromessage = failure.GetType().Name + ": " + failure.Message + " - " + failure.HowToResolve;
    }
    
    }

    Thats my application Start. How to exit the application if there is any failure in validationFailures?

    Can I do this instead of the foreach loop

    bool ValidLicense = !validationFailures.Any();
    
    if (!ValidLicense)
    {
    //Do something to exit the application. I dont know yet what I can do here
    HttpRuntime.UnloadAppDomain(); // Can I do this?
    }

    or is there a better logic than this

    Sunday, August 9, 2015 11:25 AM
  • User325035487 posted

    Did I post this in the wrong location?

    Monday, August 10, 2015 7:03 AM
  • User325035487 posted

    Ok. I did this now in Application_Start event of my global.asax to exit the application if license file has been manipulated with.

            var path = Server.MapPath("~/App_Data/Backup/License.lic");
            string licensexml = File.ReadAllText(path, System.Text.Encoding.UTF8);
            var license = License.Load(licensexml);
            string publicKey = "MIIBKjCB4wYHKoZIzj0CATCB1wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEIQNrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClgIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABFjISTS5nQeiWWtd/Wnq/9Hl+NW8OfzsHkU0xe68rrX9cSnHAQKA5+V8n22g4vjCo4qggNUPBXUzoqdDVtjFILw=";
            var validationFailures = license.Validate()
                                            .ExpirationDate()
                                                .When(lic => lic.Type == LicenseType.Trial)
                                            .And()
                                            .Signature(publicKey)
                                         .AssertValidLicense();
            int i = 1;
            string erromessage = "";
            foreach (var failure in validationFailures)
            {
                erromessage = failure.GetType().Name + ": " + failure.Message + " - " + failure.HowToResolve;
            }
            if (erromessage != "")
            {
               HttpRuntime.UnloadAppDomain();
            }

    But now just need to

    1. Prevent application from running if some one edits the global.asax file to remove the license check. : Guys can really appreciate some input about this. Like can i check the file md5 or something and save that in the license file itself and validate that during run time?
    2. and then to make sure that this license is valid for current domain only and cannot be easily copied to another pc.
    Monday, August 10, 2015 10:37 AM
  • User325035487 posted
        //License Validation
        var path = Server.MapPath("~/App_Data/Backup/License.lic");
        var keypath = Server.MapPath("~/App_Data/Backup/key.txt");
        string currentdomain = Request.ServerVariables["LOCAL_ADDR"];
        string licensexml = "";
        string erromessage = "";
        string domainip = "";
        if (File.Exists(path) && File.Exists(keypath))
        {
            licensexml = File.ReadAllText(path, System.Text.Encoding.UTF8);
            var license = License.Load(licensexml);
            string publicKey = File.ReadAllText(keypath, System.Text.Encoding.UTF8);
            var validationFailures = license.Validate()
                                            .ExpirationDate()
                                                .When(lic => lic.Type == LicenseType.Trial)
                                            .And()
                                            .Signature(publicKey)
                                         .AssertValidLicense();
            int i = 1;
            //Read Data
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(licensexml);
            XmlNode node = xmlDoc.SelectSingleNode("/License/ProductFeatures/Feature[@name='Domain IP']");
            
            domainip = node.InnerText;
            foreach (var failure in validationFailures)
            {
                erromessage = failure.GetType().Name + ": " + failure.Message + " - " + failure.HowToResolve;
                <p> @i - @erromessage</p>
                i++;
            }
            if (erromessage == "")
            {
                <p>License Valid on Domain: @domainip - Currentdomain: @currentdomain</p>
            }
        }
        else
        {
            HttpRuntime.UnloadAppDomain();
        }
        if (erromessage != "" || licensexml == "" || domainip != currentdomain)
        {
            HttpRuntime.UnloadAppDomain();
        }

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, August 10, 2015 11:43 AM