Blog

Posts about technology and arts.

Geek Vacation 2016

I just had a two week vacation, and I tried to use my time to rest, play some music, and complete a geek todo-list.

The list included things that I used some time ago but wanted to refresh my memory, things that I already used but never spent time reading the manuals, and other things that I saw somewhere but never actually used in any project.

Here the complete list, with the items that were completed highlighted. Some links with pointers to what I used to study.

Going to have less spare time now for Open Source and learning the rest of the stuff on this list, but there’s always some books to read, and things to learn anyway right ¯\(ツ)

Deploying WAR files to Tomcat with Jenkins

Table of Contents

A co-worker asked me this week about how to deploy a WAR file to Tomcat with Jenkins. In my team we are currently maintaining and deploying about 10 Java web systems, but we have no consistent way of deploying the applications to Tomcat yet. In the past I used Ant, Maven, Cargo, Grunt, and Jenkins, so I decided to write this short post to show a few different ways it can be achieved, à la Perl’s TMTOWTDI motto.

#1 Deploying with custom scripts

At first you may be tempted to write your own script to deploy to Tomcat with some Shell, Perl, Python or Java. But I think I would choose this option only because either I needed some feature that is not available in the other options, or in order to call other tasks or debug some problem.

Example:

$ docker run -d -p 8888:8080 jeanblanchard/tomcat:8
$ git clone https://github.com/spring-projects/spring-petclinic.git && cd spring-petclinic && mvn package
$ curl --upload-file target/petclinic.war "http://admin:admin@localhost:8888/manager/text/deploy?path=/spring-petclinic&update=true"
OK - Deployed application at context path /spring-petclinic

Drawing sketch: Cheese

For redditgetsdrawn

Learning afl and testing MapServer

afl is a fuzzer, an application that combines a series of algorithms in order to try invoking programs with several different input values. It then analyses the application execution flow given different test case scenarios. You can read more about fuzzing at this OWASP page, or in other blogs that I also used while learning about afl 1 2

At work we are using MapServer for serving WFS and WMS. And I am using it for the NZ OpenStreetMap maps too. MapServer is written in C++ and is normally exposed as a CGI script, so I thought it was worth learning about afl and trying it on MapServer, as in case it finds any interesting bug I can submit it to the MapServer project.

How does the Jenkins Credentials Plug-in store passwords?

Jenkins Credentials Plug-in manages credentials stored in Jenkins. These credentials can be used in many jobs and by plug-ins for executing SSH commands, authenticating to systems, or running other commands that need some sort of authentication or authorisation.

I recently used its API for the first time in the BioUno figshare Plug-in to store OAuth 1.0 credentials (consumer key, consumer secret, token key, token secret). This blog post has more details about how we used the plug-in, but this post is specifically on how the passwords are stored by Jenkins.

Secret and ciphers

Jenkins stores its configuration on disk as XML using the XStream library. Plug-in developers using the Credentials Plug-in API must use the Secret class to encrypt sensitive information.

The Secret.fromString method is responsible for creating a cipher from a given String. As in the Secret Javadoc, “this is not meant as a protection against code running in the same VM, nor against an attacker who has local file system access on Jenkins master”. But at least makes things more complicated :-)

public static Secret fromString(String data) {
    data = Util.fixNull(data);
    Secret s = decrypt(data);
    if(s==null) s=new Secret(data);
    return s;
}

The first line simply replaces a null string by an empty “”, or keeps the current value of not null.

After that, the decrypt method is called.

public static Secret decrypt(String data) {
    if(data==null)      return null;
    try {
        byte[] in = Base64.decode(data.toCharArray());
        Secret s = tryDecrypt(KEY.decrypt(), in);
        if (s!=null)    return s;

        // try our historical key for backward compatibility
        Cipher cipher = getCipher("AES");
        cipher.init(Cipher.DECRYPT_MODE, getLegacyKey());
        return tryDecrypt(cipher, in);
    } catch (GeneralSecurityException e) {
        return null;
    } catch (UnsupportedEncodingException e) {
        throw new Error(e); // impossible
    } catch (IOException e) {
        return null;
    }
}

The KEY.decrypt() call will return a javax.crypto.Cipher. The Cipher class is handled in CryptoConfidentialKey in Jenkins API, where it defines the algorithm used to create the cipher: AES.

Jenkins has also a ConfidentialStore, that is required to create the cipher. This class must be initialized before someone tries to create or read a cipher. This extra step also increases security, though access to the JVM is still a problem.

It is a bit late, so it is all for today. In summary: the credentials plug-in gives you a central place to manage credentials, but it is up to plug-in developers to use it. Sensitive values can be encrypted with AES on disk. So it is important that your file permissions, ACL and system auditing processes are in place and well maintained and monitored.

Happy hacking!

Subscribe