Zimbra Strong SSL/TLS Cipher Suites

Apparently, even in 2016, Java (and by extension Zimbra) ships without support for strong crypto. Geopolitics == retarded.

Anyway, in order to get strong crypto up and running in Zimbra Webmail, you’ll need to download the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files for JDK/JRE 8.

Unzip the file and overwrite the JARs in /opt/zimbra/java/jre/lib/security.

But wait, that’s not enough. A bunch of default cipher suites are old and weak, or are vulnerable to the Logjam Attack. You can disable all that cruft as follows:

zmprov mcf +zimbraSSLExcludeCipherSuites SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA \
+zimbraSSLExcludeCipherSuites SSL_DHE_DSS_WITH_DES_CBC_SHA \
+zimbraSSLExcludeCipherSuites SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA \
+zimbraSSLExcludeCipherSuites SSL_DHE_RSA_WITH_DES_CBC_SHA \
+zimbraSSLExcludeCipherSuites SSL_RSA_EXPORT_WITH_DES40_CBC_SHA \
+zimbraSSLExcludeCipherSuites SSL_RSA_EXPORT_WITH_RC4_40_MD5 \
+zimbraSSLExcludeCipherSuites SSL_RSA_WITH_DES_CBC_SHA \
+zimbraSSLExcludeCipherSuites TLS_RSA_WITH_RC4_128_MD5 \
+zimbraSSLExcludeCipherSuites SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA \
+zimbraSSLExcludeCipherSuites SSL_RSA_WITH_3DES_EDE_CBC_SHA \
+zimbraSSLExcludeCipherSuites SSL_RSA_WITH_RC4_128_MD5 \
+zimbraSSLExcludeCipherSuites SSL_RSA_WITH_RC4_128_SHA \
+zimbraSSLExcludeCipherSuites TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA \
+zimbraSSLExcludeCipherSuites TLS_ECDHE_RSA_WITH_RC4_128_SHA \
+zimbraSSLExcludeCipherSuites TLS_RSA_EXPORT_WITH_DES40_CBC_SHA \
+zimbraSSLExcludeCipherSuites TLS_RSA_WITH_3DES_EDE_CBC_SHA \
+zimbraSSLExcludeCipherSuites TLS_RSA_WITH_AES_128_CBC_SHA \
+zimbraSSLExcludeCipherSuites TLS_RSA_WITH_AES_128_CBC_SHA256 \
+zimbraSSLExcludeCipherSuites TLS_RSA_WITH_AES_128_GCM_SHA256 \
+zimbraSSLExcludeCipherSuites TLS_RSA_WITH_DES_CBC_SHA \
+zimbraSSLExcludeCipherSuites TLS_DHE_RSA_WITH_AES_128_CBC_SHA \
+zimbraSSLExcludeCipherSuites TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 \
+zimbraSSLExcludeCipherSuites TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 \
+zimbraSSLExcludeCipherSuites TLS_DHE_RSA_WITH_AES_256_CBC_SHA \
+zimbraSSLExcludeCipherSuites TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 \
+zimbraSSLExcludeCipherSuites TLS_DHE_RSA_WITH_AES_256_GCM_SHA384

Finally, restart zmmailboxdctl. You’re good to go :-).

Endless Locale Bugs

This isn’t the first time I’ve ranted about Locale related issues. It probaly won’t be the last, either.

Currently my biggest gripe is with convenience methods in Java which rely on platform defaults, and are thus platform-specific. For instance, the venerable System.out.println() will terminate your line with whatever your platform thinks a line ending should be. Printing dates or numbers will try to use your platform Locale. Writing a string to a file will default to platform encoding.

Some of these defaults can be controlled at run time, others require JVM startup options. This is all horribly wrong. This results in all kinds of unexpected behaviour. It’s error-prone. None of this should be allowed to happen. Any method that assumes platform-specific magic should be deprecated. Which is exactly what I’ll do, as soon as I can figure out how to write a Sonar plugin to detect all this nonsense.

Getting started with JAX-RS & Gradle

Managed to waste an hour of my life today, trying to set up a JAX-RS + Gradle project. Gradle wasn’t really the problem, nor was JAX-RS, but putting it all together in a way that works took longer than expected.

So without further ado, I present to you a simple quickstart project you can use to kickstart JAX-RS + Gradle projects.

The Gradle build file is pretty minimalistic. There’s no need for web.xml. And I’ve included an example resource.

build.gradle:

description = 'JAX-RS Quickstart'
group = 'org.lick.me.jaxrs'
version = '1.0-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'eclipse'
sourceCompatibility = 1.8
 
repositories {
        mavenCentral()
}
 
 
buildscript {
        repositories {
                jcenter()
        }
        dependencies {
                // Embedded Jetty 9 Gradle Plugin
                classpath (group: 'com.sahlbach.gradle', name: 'gradle-jetty-eclipse-plugin', version: '1.9.+')
        }
}
apply plugin: 'jettyEclipse'
apply plugin: 'war'
 
dependencies {
        // JAX-RS 2.0(.1)
        compile 'javax.ws.rs:javax.ws.rs-api:2.0.1'
 
        // Jersey 2.15
        compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.15'
 
        // Servlet 3
        compile 'javax.servlet:javax.servlet-api:3.1.0'
}

Extra quick quickstart:

git clone git@github.com:Nimlhug/jax-rs-quickstart.git
cd jax-rs-quickstart
gradle jettyEclipseRun

More Open Source donations

The end of the year is upon us, and the kind folks over at GnuPG (gpg) are asking for donations. I pitched in along with many others, and I would encourage anyone who values online privacy to do the same. GPG is a critical part of open source development, extremely useful for signing releases or securing communications.

If you have a little cash to spare, consider making a donation to a FOSS project you like or use. A little goes a long way. Thanks!

Gradle gotcha: duplicate project names

Assume the following project structure:

Product
β”œβ”€β”€build.gradle
β”œβ”€β”€settings.gradle
β”œβ”€β”€FeatureA
β”‚Β Β  β”œβ”€β”€ Foo
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ build.gradle
β”‚   β”œβ”€β”€ Bar
β”‚   β”‚   β”œβ”€β”€ build.gradle
β”œβ”€β”€FeatureB
β”‚   β”œβ”€β”€ Foo
β”‚   β”‚   β”œβ”€β”€ build.gradle
β”‚   β”œβ”€β”€ Quf
β”‚   β”‚   β”œβ”€β”€ build.gradle

I don’t think this is a terribly unreasonable structure: we have a product with a bunch of features, and each feature is split into a couple of modules. This works just fine in gradle. As long as FeatureB/Foo doesn’t have a dependency on FeatureA/Foo. Gradle doesn’t seem to be terribly fond of multi-module projects. At least not when you have a deeper, nested structure.

As soon as FeatureB/Foo has a dependency on FeatureA/Foo, gradle goes belly up. It won’t tell you, though. It’ll just quietly carry on. It won’t resolve the dependency, and you’ll end up with compile errors.

FeatureB/Foo/build.gradle:

dependencies {
	compile project(':FeatureA:Foo')
}

The reason is actually quite simple. Gradle uses the directory name as the project name. Instead of looking at the whole path in the tree, which would be a lot more sensible, it just looks at the last leaf in the tree. So we have two projects named Foo, and gradle chokes. Not giving an error/warning strikes me as a bug, though, but still. Not terribly unreasonable.

Thankfully, there’s a fix. It involves renaming your projects via settings.gradle in the root project:

settings.gradle:

// List our projects/subprojects
include ':FeatureA:Foo'
include ':FeatureA:Bar'
include ':FeatureB:Foo'
include ':FeatureB:Quf'
 
// Rename each child project to its path: Foo becomes FeatureA-Foo or FeatureB-Foo, depending on the Foo.
rootProject.children.each { p ->
        p.children.each { module ->
                module.name = p.name + '-' + module.name
        }
}

Now you can add a project dependency and things will Just Work™:

dependencies {
	compile project(':FeatureA:FeatureA-Foo')
}

All fixed. Much better.

Laptops

My Thinkpad x230 gave me a bit of a scare recently. The display died out of the blue, and Lenovo’s support was an absolute nightmare. In spite of next business day on site warranty, it took them nearly two weeks to actually fix the bloody thing. The first time the tech showed up, he replaced the broken panel with another broken panel. Not too useful, that.

While I was in limbo, unsure if it would ever get fixed under warranty, and wondering how much it would cost me to have it fixed, I spent some time researching alternatives.

Sadly, I found none. It seems like literally no one makes laptops for people who use use them anymore. There’s loads of consumer-grade crap out there, but nothing useful. Especially in the 12.5″ range.

There are a couple of recurring failures.

Keyboard & Mouse

x240

The Thinkpad x240 — “new and improved” — comes with a trackpad that takes up more space than the fucking keyboard. The top buttons (used in conjunction with the nipple) are part of the trackpad. Apparently if you disable the trackpad, you’re out of luck and out of buttons. Great. Turning off the trackpad, of course, is mandatory, given that the thing is so fucking huge that my thumbs constantly touch it inadvertently. Especially annoying when focus follows pointer.

The picture doesn’t do it justice, but another problem with the x240 is that the function keys got smaller and are now closer to the number row than before. Makes for an overall less enjoyable experience.

207647

dellXPS13-9333_3

These ASUS & Dell pieces of shite both seem to be missing a bunch of keys (page up, page down, home, insert, end, …) and seem to have completely flat keys. Apparently there’s a market for people who don’t type.

Mechanical failures waiting to happen

xps

asus

Whoever designed these amazing ultra portable laptops seems to have forgotten that people will be moving around with them. Those display look like they’ll snap in half the first time you bump into anything. And seriously, who the fuck needs a detachable display? Who buys this? What do they do for a living? Not software engineers, that’s for sure.

Touchscreen

Apparently everybody and their grandmother wants a touchscreen. I can’t for the life of my imagine why. Having to use a mouse (due to terrible window management and non-keyboard-friendly websites) is already a waste of time. Having to touch my screen (and leaving greasy fingerprints everywhere) is even worse. Fuck that shit.

So …

Laptops that don’t suffer from any of the above flaws are few and far between, and usually have a CPU that’s slower than my phone’s, or less memory than my toaster. Anything that ships with an AMD CPU isn’t even worthy of being a coaster, either. Makes you wonder how they’re still relevant.

Apparently there are literally no laptops on the market for software engineers. There’s all kinds of crap designed around this Windows 8 insanity with its useless tablet-like interface. I’m sure these machines are perfectly fine for consuming information like some kind of brain dead zombie, but there’s no universe in which these machines are useful for creating or getting any work done.

Needless to say, I’m quite happy that Lenovo did repair my x230 in the end. Hopefully it’ll outlive its warranty. With a bit of luck, the x250 or x260 won’t suck quite as much…

Fun with Gradle Plugins – Integration Tests

Currently in the process of migrating a 10000 line Ant build to Gradle. Not quite as fun as it sounds, but at least the Gradle build should be faster, more maintainable and hopefully free from cruft.

One of this build’s peculiarities is that it executes Unit Tests and Integration Tests at different points in the build cycle. The Integration tests rely on nasty things like databases, IBM MQ and LDAP. Things that are difficult to mock out & slow your build down to a grind if you execute these tests too frequently. Some of them are really System tests, if you’re being pedantic, but let’s just ignore that. The point is, there’s a category of tests that we don’t want to see executed during the normal unit test execution.

Full code available on GitHub.

Selim Γ–ber explains how to accomplish this on his blog. I wanted to see if I could turn it into a plugin instead, as it will have to be applied to many different projects (made more difficult by a heterogenous coding environment. Not everything is a Java project).

The Goal

The goal of this plugin is to be able to execute tests in src/integration/java by executing the integrationTest target. These tests will expressly not be executed during the normal build cycle. These are to be run manually (or by your CI engine or whatever) periodically, as opposed to continuously on each build.

buildSrc

The buildSrc folder is Gradle’s magic box. It lives in your project root and contains — as the name might imply — some of your build’s source code. Gradle is smart enough to pick up on the stuff there, and will automagically compile it when it changes.

I chose groovy for this plugin, so I’ll just let Gradle know about that, and I’ll politely ask it to make the Gradle API available for me to use.

buildSrc/build.gradle

apply plugin: 'groovy'
 
repositories {
	mavenCentral()
}
 
dependencies {
	compile gradleApi()
}

Next is the actual plugin.

buildSrc/src/main/groovy/org/lick/me/gradle/IntegrationTestPlugin.groovy

package org.lick.me.gradle
 
import org.gradle.api.Plugin
 
import org.gradle.api.Project
import org.gradle.api.tasks.testing.Test
 
/**
 * Applying this plugin will let gradle know that the project contains integration tests.
 * These can be executed at a later point in time than unit tests -- when a database etc 
 * become available. 
 */
class IntegrationTestPlugin implements Plugin<Project> {
	@Override
	void apply(final Project project) {
 
		project.sourceSets {
			integTest {
				java.srcDir project.file('src/integration/java')
				resources.srcDir project.file('src/integration/resources')
			}
		}
 
		project.dependencies {
			integTestCompile project.sourceSets.main.output
			integTestCompile project.configurations.testCompile
			integTestCompile project.sourceSets.test.output
			integTestRuntime project.configurations.testRuntime
		}
 
		project.task('integrationTest', type: Test, description: 'Runs the integration tests.', group: 'Verification') {
			testClassesDir = project.sourceSets.integTest.output.classesDir
			classpath = project.sourceSets.integTest.runtimeClasspath
		}
 
		project.task('allTests', dependsOn: [project.test, project.integrationTest], description: 'Runs all tests.', group: 'Verification') {
 
		}
	}
}

Now all we need is a bit of magic to let Gradle know that we want to be able apply this plugin in other projects.

buildSrc/src/main/resources/META-INF/gradle-plugins/integrationTests.properties

implementation-class=org.lick.me.gradle.IntegrationTestPlugin

Now we can add the plugin to your projects.

apply plugin: 'integrationTests'

Running gradle tasks will now result in two extra tasks in the Verification section.

tasks

Git pre-commit hooks

Git’s pre-commit hooks are pretty useful. You could use them, for instance, to run your tests and abort the commit if there are failures. All you have to do is write a simple shellscript. The example below runs a php syntax check on all php files and aborts the commit if it detects anything invalid. It’s based on a script that was going around at $work, no idea who the original author is, but kudos!

Save this as .git/pre-commit, and make sure you make it executable (chmod u+x)!

 #!/bin/sh

syntax_errors=0
error_msg=$(mktemp /tmp/error_msg.XXXXXX)

if git rev-parse --verify HEAD >/dev/null 2>&1
then
        against=HEAD
else
        # Initial commit: diff against an empty tree object
        against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi

# Get a list of modified php files and run php -l against them.
for indexfile in `git diff-index --diff-filter=AM --name-only --cached $against | egrep '\.(php)'`
do
    # Don't check empty files
    if [ `git cat-file -s :0:$indexfile` -gt 0 ]
    then
        case $indexfile in
            *.php )
                # Check php syntax
                git cat-file blob :0:$indexfile | php -l > $error_msg ;;
        esac
        if [ "$?" -ne 0 ]
        then
            echo -n "$indexfile: "
            cat $error_msg
            syntax_errors=`expr $syntax_errors + 1`
        fi
    fi
done

rm -f $error_msg

if [ "$syntax_errors" -ne 0 ]
then
    echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
    echo "@@   Error: syntax errors found, aborting commit.   @@"
    echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
    exit 1
fi

Extending or modifying this script to suit your needs is pretty trivial. You can expand the egrep and case to include any other filetype you want to perform magic on, or you can run your unit tests after the loop, or send an e-mail, or make coffee, etc.

On Ruby & PHP

So I quit my job. That was a relatively big change for me, after spending 3 years sat on the same chair working with the same team. But I felt it was time for a change. The new job is quite a bit different from the old one. One rather obvious difference is the programming language .. I’ve gone back to my proverbial roots and am now churning out PHP on a daily basis. And because I’m such a programming nut, I’m working on some after-hours Ruby projects as well.

PHP and Ruby are both obviously very different from Java – and very different from each other. Sometimes in good ways, sometimes in bad ways. Syntax wise, PHP and Java are very similar. The dollar sign on my keyboard is definitely seeing a lot more action now, but other than that not many dramatic finger changes are required. PHP doesn’t have have a bunch of things I like, like final method arguments, multit-hreading or a half decent collection of standard classes. What it does have is excellent documentation and easy & interesting meta-programming. That, and it’s obviously much more tailored for the web than Java. For the first time in 3 years I *don’t* actually need a whole armada of frameworks just to get something simple done. Still .. I miss my (Concurrent)HashMap, ArrayList, and most importantly my trusted BigDecimal.

And then there’s Ruby .. Even after a couple of months of Ruby, I have very mixed feelings about it. The documentation sucks. Don’t argue with me, it really does suck big fucking donkey balls. RDoc (especially online) is to JavaDoc what Spam is to nice and tasty Prosciutto. Then there’s the lack of backwards compatibility (granted, Java may take this a bit too far, but still).

And then … there’s the syntax. This is where my feelings are mixed, rather than plain negative. There’s too much choice. You can mix and match a bunch of styles, do..end, curly brackets, semicolons or no semicolons, method arguments with or without braces, and the list probably goes on. This leads to code that’s hard to read (and thus hard to maintain), especially when different people stick to different styles. On the other hand, it also leads to nice syntactic sugar. Clever use of methods can make it look like you’re defining your own keywords, which is very nice for creating your own DSLs. It’s also rather nice to have Operator Overloading, and being able to treat everything like an object also has its benefits.

Still .. my feelings remain mixed. And in spite of everything, I feel like Java is still the only choice for Serious work. Not only because of the amazing documentation, the excellent standard library or even the massive community, but also for the amazing JVM, its security model and its thriving ecosystem.

Java ain’t dead, folks.