Saturday, March 22, 2008

License management plugin for Grails application

I have been recently working on a plugin that provides ability to securely create, install and verify license for closed source grails applications. This plugin utilizes TrueLicense Library Collection (TLC). You can download the plugin here.

Installation

grails install-plugin

Usage

* Generate license file: grails generate-license
* Start app: grails run-app
* Instal/verify license at http://localhost:8080/your_app/license. If you try to access your app without installing license, you will be redirected to this page.

Components

* /plugins/license-0.1/etc/privateKey.store - private key file. This never gets included in your WAR. (You should generate your own private/public keys with keytool command. see tips section below)
* /plugins/license-0.1/etc/LicensePrivateConfig.properties - holds all necessary configuration to create a license such as issuer, holder, validity etc. Again not included in WAR
* /plugins/license-0.1/conf/publicCerts.store - public key file. This is included in WAR
* /plugins/license-0.1/conf/LicensePublicConfig.groovy - holds all necessary information required for the client. Included in WAR
* /plugins/license-0.1/controller/LicenseController - Install, verify license
* /plugins/license-0.1/services/LicenseService - Install, verify license
* /plugins/license-0.1/conf/LicenseFilter - defines which controllers, actions need to be protected.

Tips

* To generate private key:
keytool -genkey -alias privatekey -keystore privateKeys.store
* To generate public key
keytool -export -alias privatekey -file certfile.cer -keystore privateKeys.store
keytool -import -alias publiccert -file certfile.cer -keystore publicCerts.store
* The system preferences are stored in the registry in windows and file system (/etc/.java/) in Linux. You may need appropriate permissions to be able to do this.

12 comments:

  1. Björn WilmsmannApr 11, 2008 05:03 AM

    I’ve been trying to get the plugin to work under Grails 1.0.2 during the last few hours. However, I basically run into two problems:

    - If I generate a license with the key pair that comes with the plugin, the license won’t be accepted and the following exception is thrown: service.LicenseService License could not be installedde.schlichtherle.xml.PersistenceServiceException: java.lang.ClassCastException: org.apache.xerces.jaxp.SAXParserFactoryImpl . Usually, I would assume this is due to conflicting xercesImpl.jarS. However, in my app there is only one, that is the one that comes with Grails 1.0.2
    - After having generated my own private / public key pair and changing the config settings accordingly, ‘grails generate-license’ simply prints out ‘null’, which seems to originate from line 68 in GenerateLicense.groovy: LicenseManager lm = new LicenseManager(licenseParam). I have double-checked the settings in conf/LicensePublicConfig.groovy and etc/LicensePrivateConfig.properties.


    Best regards,
    Bjoern Wilmsmann

    PS: Besides, this plugin should definitely be added to the official Grails plugins page, as it provides a very useful feature.

    ReplyDelete
  2. The exception indicates that probably there is a conflicting jar. I have tried the plugin with both grails 1.0.1 and 1.0.2 and works fine. Can you try the plugin with a simple HelloWorld app? If you still have problems, let me know your OS, java ver etc

    BTW, the plugin has already been added to grails repo. You should be able to install the plugin by grails install-plugin license.

    - Mano

    ReplyDelete
  3. I haven’t got a chance to test the plugin with Grails 1.1. Will try to get to it soon.

    ReplyDelete
  4. Hi,

    Have you got plans to upgrade this plugin to work with grails 1.1 ?

    Thanks

    SiTo

    ReplyDelete
  5. Hi there,

    I recently tried to use the plugin on Grails 1.1.1 resulting in :
    Error executing script GenerateLicense: java.io.FileNotFoundException: /plugins/license-0.1/grails-app/etc/privateKeys.store

    I tried to fix it but I can't identify the problem here. Changing GenerateLicense.groovy privateKeyPath to "${baseDir}${pluginPath}/grails-app/etc/${licenseConfig.license.privateKeyFile}" did not help.
    But creating new java.io.File with this path works fine.

    Do you still plan to update the plugin to work with 1.1?

    Greetings,
    Chris

    ReplyDelete
  6. Hi again,

    further Analysis showed that truelicense class AbstractKeyStoreParam
    is implemented as follows:
    --------
    InputStream in = clazz.getResourceAsStream(resource);
    --------

    GenerateLicense.groovy does:
    --------
    def privateKeyFile = "${pluginPath}/grails-app/etc/${licenseConfig.license.privateKeyFile}"

    new DefaultKeyStoreParam(getClass(), privateKeyPath ...
    --------
    ...so getResourceAsStream is executed on the class in the grails scriptCache pointing to a nonexistent resource there.

    Greetings,
    Chris

    ReplyDelete
  7. Chris:

    Thanks for your comment. I've released an updated version (V 0.2 compatible with Grails 1.1.1). Let me know if it works for you.

    ReplyDelete
  8. Hi,
    Is this plugin compatible with grails 1.2.1? I've installed on grails 1.2.0 but i got this error when i generate the license.

    Error executing script GenerateLicense: java.io.FileNotFoundException: license-c
    onfig/privateKeys.store

    I've checked on the folder, the privateKeys.store is exist. Am i missed something or it is not compatible with grails 1.2.1??

    Thanks in advanced.

    ReplyDelete
  9. I haven't tested the plugin with Grails 1.2.1. I will try to look into that

    ReplyDelete
  10. i've tried plugin on grails 1.1.1 on dummy application. i still got the same exception during generating the license. but the application is running well, then i submit the privateKey.store, it seem like the license is invalid or expired. I've created new filekey.store but it goes the same result. Please advice. Thanks.

    ReplyDelete
  11. Hi,
    I've got the same exception here. I replaced

    def privateKeyPath = "license-config/${licenseConfig.license.privateKeyFile}"

    with

    def privateKeyPath = "${basedir}/license-config/${licenseConfig.license.privateKeyFile}"

    and the resource definitely exists and has full permissions

    Caused by: java.io.FileNotFoundException: /media/sda3/pmhome-ubuntu/GestFlow/license-config/privateKeys.store
    at de.schlichtherle.license.AbstractKeyStoreParam.getStream(Unknown Source)
    at de.schlichtherle.license.LicenseNotary.getKeyStore(Unknown Source)
    at de.schlichtherle.license.LicenseNotary.getPrivateKey(Unknown Source)
    at de.schlichtherle.license.LicenseNotary.sign(Unknown Source)
    at de.schlichtherle.license.LicenseNotary.sign(Unknown Source)
    at de.schlichtherle.license.LicenseManager.create(Unknown Source)
    at de.schlichtherle.license.LicenseManager.store(Unknown Source)
    at de.schlichtherle.license.LicenseManager.store(Unknown Source)
    at GenerateLicense$_run_closure4.doCall(GenerateLicense:85)
    at GenerateLicense$_run_closure1.doCall(GenerateLicense:20)
    at gant.Gant$_dispatch_closure4.doCall(Gant.groovy:324)
    ... 10 more

    Also tried replacing

    def privateKeyStoreParam = new DefaultKeyStoreParam(this.getClass(), privateKeyPath, licenseConfig.license.privateKeyAlias, ...

    with

    def privateKeyStoreParam = new DefaultKeyStoreParam(Class.getClass("java.lang.ClassLoader
    "), privateKeyPath, licenseConfig.license.privateKeyAlias, ...

    Same thing
    Thanks
    Paolo

    ReplyDelete
  12. Hi again,

    explanation here
    http://www.grails.org/doc/1.1.x/guide/2.%20Getting%20Started.html
    under 'Script changes' point 3

    Actually, saving privateKeys.store under ~/.grails/1.2.1/scriptCache makes it working because it is in the classpath
    Paolo

    ReplyDelete