Aug 032016
 

xmms logoYeah, I’m still using the good old xmms v1 on Linux and UNIX. Now, the boxes I used to play music on were all 32-bit x86 so far. Just some old hardware. Recently I tried to play some of my [AAC-LC] files on my 64-bit Linux workstation, and to my surprise, it failed to play the file, giving me the error Pulse coding not allowed in short blocks when started from the shell (just so I can read the error output).

I thought this had to have something to do with my file and not the player, so I tried .aac files with ADTS headers instead of audio packed into an mp4/m4a container. The result was the same. Also, the encoding (SBR/VBR or even HE-AAC, which sucks for music anyway) didn’t make a difference. Then I found [this post] on the Gentoo forums, showing that the problem was really the architecture. 32-bit builds wouldn’t fail, but the source code of the [libfaad2] decoding library of xmms’ mp4 plugin wasn’t ready for 64-bit.

xmms’ xmms_mp4Plugin-0.4 comes with a pretty old libfaad2, 2.0 or something. I will show you how to upgrade that to version 2.7, which is fixed for x86_64 (Readily fixed source code is also provided at the bottom). We’ll also fix up other parts of that plugin so it can compile using more modern versions of GCC and clang, and my test platform for this would be a rather conservative CentOS 6.8 Linux. First, get the source code:

I’m assuming you already have xmms installed, otherwise obtain version 1.2.11 from [here]!

Step 1, libfaad2:

Unpack both archives from above, then enter the mp4 plugins’ source directory. You’ll find a libfaad2/ directory in there. Delete or move it and all of its contents. From the faad2 source tree, copy the directory libfaad/ from there to libfaad2/ in the plugins’ directory, replacing the deleted one. Now that’s the source, but we also need the updated headers so that the xmms plugin can link against the newer libfaad2. To do that, copy the two files include/faad.h and include/neaacdec.h from the faad2 2.7 source tree to the directory include/ in the plugin source tree. Overwrite faad.h if prompted.

Step 2, libmp4v2:

Also, the bundled libmp4v2 of the mp4 plugin is very old and broken on modern systems due to code issues. Let’s fix them, so back to the mp4 plugin source tree. We need to fix some invalid pure specifiers in the following files: libmp4v2/mp4property.h, libmp4v2/mp4property.cpp, libmp4v2/rtphint.h and libmp4v2/rtphint.cpp.

To do so, open them in a text editor and search and replace all occurences of = NULL with = 0. This will fix all assignments and comparisons that would otherwise break. When using vi or vim, you can do :%s/=\sNULL/= 0/g for this.

On top of that, we need to fix a invalid const char* to char* conversion in libmp4v2/rtphint.cpp as well. Open it, and hop to line number 325, you’ll see this:

  1. char* pSlash = strchr(pRtpMap, '/');

Replace it with this:

  1. const char* pSlash = strchr(pRtpMap, '/');

And we’re done!

Now, in the mp4 plugins’ source root directory, run $ ./bootstrap && ./configure. Hopefully, no errors will occur. If all is ok, run $ make. Given you have xmms 1.2.11 installed, it should compile and link fine now. Last step: # make install.

This has been tested with my current GCC 4.4.7 platform compiler as well as GCC 4.9.3 on CentOS 6.8 Linux. Also, it has been tested with clang 3.4.1 on FreeBSD 10.3 UNIX, also x86_64. Please note that FreeBSD 10.3 needs extensive modifications to its build tools as well, so I can’t provide fixed source for this. However, packages on FreeBSD have already been fixed in that regard, so you can just # pkg install xmms-faad2 and it’s done anyway. This is likely the case for several modern Linux distros as well.

Let’s play:

xmms playing AAC-LC Freebsd 10.3 UNIX on x86_64

Yeah, it works. In this case on FreeBSD.

And the shell would say:

2-MPEG-4 AAC Low Complexity profile
MP4 - 2 channels @ 44100 Hz

Perfect! And here is the [fixed source code] upgraded with libfaad2 2.7, so you don’t have to do anything by yourself other than $ ./bootstrap && ./configure && make and # make install! Ah, actually I’m not so sure whether xmms itself builds fine on CentOS 6.8 from source these days… Maybe I’ll check that out another day. ;)

Aug 092013
 

Filezilla logoI think I can say without raising too much critisism, that [Filezilla] is one of the best if not the best cross-platform FTP client ever built. It works on many operating systems like Windows, Linux, BSD UNIX etc. Now, I’ve been stuck with an older version of Filezilla, namely 3.5.2 because of a [tedious bug] that arose when you built the client and linked it against GnuTLS 2.8.x, which is typically what you’ll have when you’re running some Enterprise Linux distribution like me (CentOS 6.4 in my case).

If you’re using SSL-enhanced FTP servers which understand FTPS and FTPES (not to be confused with the SSH-based SFTP), any Filezilla version >=3.5.3 linked against any GnuTLS 2.8.x will break when connecting to such a server using SSL/TLS. So while Filezilla 3.7.3 compiled just fine on my system, it broke at runtime when doing that. See here:

Broken Filezilla: Connection log

(click to enlarge)

Here is the dreaded GnuTLS -50 error. From what I have read, it’s a problem that comes from a bug in the way SSL handshaking is done. It appears that if a server supports low-security ciphers in its cipher suite, the negotiation will break, as Filezilla only allows high-security ciphers since 3.5.3. This is somehow linked to GnuTLS 2.8.x. So even if a server supports high-security ciphers, it still breaks if low-security ones are also supported. That’s my current assumption at least. The only way seems to be to completely remove low-sec ciphers from the servers side. Which is sometimes impossible. But then..  Why does it work on Windows? Let’s first see what the latest Filezilla 3.7.3 reports on CentOS 6 Linux when asked for version numbers (under Help / About…):

Broken Filezilla: Version info

Aha. Ok. So wxWidgets 2.8.12 which I have installed myself (the packages are called wxGTK and wxGTK-devel!), SQLite 3.6.20 which comes with CentOS 6.4 and GnuTLS 2.8.5, which is also shipped with this Linux distribution. All stock then. Let’s compare that to the Windows version, which works just fine:

Working Filezilla on Windows: Version info

So the Filezilla guys used the same wxWidgets GUI libraries as I did, a slightly newer SQLite and most importantly a far newer major release of GnuTLS. Now I have tried GnuTLS 2.8.6 too, the lastest 2.8.x branch stable release, and I even tried to build and link against an unstable 2.9.9, all bugged in the same way. So the only way is to install a GnuTLS >=3.0. However, GnuTLS 3.x requires [nettle], some low-level crypto library, which CentOS doesn’t have.

On top of that, the latest version 2.7 of nettle won’t compile on CentOS 6, you’ll just get a buttload of really nasty compiler errors, but the latest GnuTLS 3.1.13 only requires nettle 2.5, so we’ll go with that. You can still get that version from [here].

Download it, and from there it’s as easy as this (you can leave out the -O3 -ffast-math in case you’re not comfortable with aggressive compiler optimizations or you run into stability issues):

tar -xzvf ./nettle-2.5.tar.gz
cd ./nettle-2.5/
export CFLAGS="-march=native -O3 -ffast-math -pipe"
export CXXFLAGS="-march=native -O3 -ffast-math -pipe"
./configure
make
su
make install

Now we can build GnuTLS 3.1.13, which can be downloaded from [here]. On my CentOS 6.4 I managed to make it link against nettle 2.5 and build like this (-O3 and -ffast-math may be omitted again):

tar -xJvf ./gnutls-3.1.13.tar.xz
cd ./gnutls-3.1.13/
export CFLAGS="-march=native -O3 -ffast-math -I/usr/local/include -L/usr/local/lib64"
export CXXFLAGS="-march=native -O3 -ffast-math -I/usr/local/include -L/usr/local/lib64"
./configure
make
su
make install

Perfect. Now please download the [latest Filezilla source code] which is currently version 3.7.3, and you should be able to link it against our brand new GnuTLS 3.1.13 in the following way (-O3 -ffast-math may be omitted again):

tar -xjvf ./FileZilla_3.7.3_src.tar.bz2
cd ./filezilla-3.7.3/
export CFLAGS="-march=native -O3 -ffast-math -pipe -I/usr/local/include -L/usr/local/lib -L/usr/local/lib64"
export CXXFLAGS="-march=native -O3 -ffast-math -pipe -I/usr/local/include -L/usr/local/lib -L/usr/local/lib64"
export LD_LIBRARY_PATH="/usr/local/lib"
./configure --with-tinyxml=builtin --with-libgnutls-prefix=/usr/local
make
su
make install

This will make sure all the linking will work and not fall back to the systems default GnuTLS 2.8.5 or any other version of the 2.8.x branch your system might have. Now if that is done, just launch Filezilla, and look at the version numbers under Help / About… again to verify it has been linked correctly:

Working Filezilla: Version infoWorking Filezilla: Connection log

In my case, GnuTLS is now even newer than the version that has been used by the developers themselves to create their Windows build. 3.1.13 instead of 3.1.11. But in any case, a version of 3.1.x that should fix the cipher negotiation problem. Take a deep breath and try your FTPS or FTPES connection now, it should work even if the server supports low-security ciphers:

Working Filezilla: Connection log

(click to enlarge)

Space magic done! It works indeed. Note that this will probably not help you, if the SSL-enhanced FTP server you want to connect to supports no high-security ciphers. Your server will need to offer at least some of those in its cipher suite. But if it does low+high, this should fix it. And by using nettle 2.5, the latest stable version of GnuTLS can still be compiled on CentOS 6, and therefore also on Scientific Linux 6 and RedHat Enterprise Linux 6. Should be somewhat similar in Debian Squeeze and maybe SuSE Linux Enterprise Desktop.

Finally, a problem solved. Now I can use the latest version of Filezilla across all my operating systems again! Funny that nobody suggested this way in the Filezilla forums. Hm. Maybe I should.

Edit: While testing PC-BSD 9.2 UNIX I have now found out, that GnuTLS 2.12.x also seems to fix this, so you don’t absolutely need GnuTLS 3.x+. See this screenshot of FileZilla on PC-BSD 9.2 (based on FreeBSD 9.2) linked against GnuTLS 2.12.23:

Filezilla with GnuTLS 2.12.23 on BSD

So yes, this also works flawlessly!

Update 2014-04-30: And finally, I found a way to build the latest stuff on CentOS 6.5 Linux, opening up the way to newer versions of Filezilla and more importantly GnuTLS. That would include [nettle 2.7.1], [GnuTLS 3.2.13] and [Filezilla 3.8.0] as of the time of writing. Compilation and having the program work at runtime was tricky though. I am not perfectly sure if my documentation is complete (if you try this and fail, just post a comment!), but I think this should get you going, skipping the easy commands like unpacking the archives etc. here and leaving out non-essential flags like “-march=native” or “-O3”. You can still add those of course. Let’s start with nettle 2.7.1, this time disabling OpenSSL glue code:

./configure --disable-openssl
make
su
make install

Now, GnuTLS 3.2.13. For this we’ll need a bit more trickery, especially for the pkg-config library detection that GnuTLS uses to locate nettle stuff, but also, unfortunately, LD_LIBRARY_PATH:

export CFLAGS="-I/usr/local/include -L/usr/local/lib64"
export CXXFLAGS="-I/usr/local/include -L/usr/local/lib64"
export LDFLAGS="-I/usr/local/include -L/usr/local/lib64"
export PKG_CONFIG_PATH="/usr/local/lib64/pkgconfig"
export LD_LIBRARY_PATH="/usr/local/lib64"
./configure
make
su
make install

After that, assuming you’re still sitting in the same shell you built and installed GnuTLS in, thus preserving the environment variable from above, continue with Filezilla 3.8.0 exactly like this:

unset LD_LIBRARY_PATH
export CFLAGS="-I/usr/local/include -L/usr/local/lib64 -L/usr/local/lib"
export CXXFLAGS="-I/usr/local/include -L/usr/local/lib64 -L/usr/local/lib"
export LDFLAGS="-I/usr/local/include -L/usr/local/lib64 -L/usr/local/lib"
./configure --with-tinyxml=builtin --with-libgnutls-prefix=/usr/local
make
su
make install

We’re not done yet though. Since we played around with an evil LD_LIBRARY_PATH to get this built and linked, our /usr/local/bin/filezilla binary will just crash with a symbol error caused by GnuTLS unable to locate certain nettle functions. I would suggest working around that by writing yourself a small launcher script to fire up Filezilla with the proper path set for its session. I’d call this script /usr/local/sbin/filezilla.sh. You can then use that to launch the program, and the code is super simple:

#!/bin/bash
export LD_LIBRARY_PATH="/usr/local/lib64"
/usr/local/bin/filezilla

Kinda dirty, but it works. And here is the result:

Filezilla 3.8.0 working with GnuTLS 3.2.13 and nettle 2.7.1 on CentOS 6.5 Linux

Besides missing a few optimization flags, this actually seems to work pretty well so far. A few tests using encrypted connections with a modern TLS v1.2 protocol AES-256-GCM cipher suggests everything is in order. Great!