Cisco Anyconnect on 64bit

I decided to take the Cisco Anyconnect 3.1 client for a spin on 64-bit Suse 12.1

The issue I am seeing is that the client launches and when it attempts to run the Cisco Secure Destop (csd) binary it chokes. The reason why is interesting:

ldd shows /opt/cisco/anyconnect/bin/vpnui (32bit) links to all needed libraries, including libcurl.so in /opt/cisco/anyconnect/lib

So this launches fine.

In turn, it calls ~/.cisco/hostscan/bin/cscan (32bit) which logs:

*/home/user/.cisco/hostscan/log/cscan.log
*

*
[Fri Oct 05 08:11:33.863 2012][cscan][debug][hs_transport_curl_load_curl] 
[/opt/cisco/anyconnect/lib/libcurl.so.3] does not have the required support 
[Fri Oct 05 08:11:33.863 2012][cscan][debug][hs_file_verify_with_killdate] verifying file 
signature: file = [/usr/lib64/libcurl.so.4], signer = (null)], type = [2] 
[Fri Oct 05 08:11:33.863 2012][cscan][debug][hs_file_verify_with_killdate] file verification 
bypassed: file = [/usr/lib64/libcurl.so.4], signer = (null)], type = [2] 
[Fri Oct 05 08:11:33.863 2012][cscan][debug][hs_dl_load_global] 
attempting to load library (/usr/lib64/libcurl.so.4) 
[Fri Oct 05 08:11:33.863 2012][cscan][warn][hs_dl_load_global] unable to load (/usr/lib64/libcurl.so.4): /usr/lib64/libcurl.so.4: wrong ELF class: ELFCLASS64*

/var/log/messages

Oct  5 08:11:33  cscan[7983]: [cscan][warn][hs_dl_load_global] 
unable to load (/usr/lib64/libcurl.so.4): /usr/lib64/libcurl.so.4: wrong 
ELF class: ELFCLASS64 
Oct  5 08:11:33  vpnui[7850]: [libcsd][all][new_connection_cb] 
*** new connection [f0c86218] from pid: [7983] *** 
Oct  5 08:11:33  kernel: cscan[7983]: segfault at f71dea58 ip 
0000000008099987 sp 00000000fff7ea20 error 7 in cscan[8048000+c7000] 

So the linker runs off to library land and comes back with /usr/lib64/libcurl.so.4, which of course is wrong ELF class.

My questions then are:

  1. ldd shows cscan is not itself linked to any libcurl, but it tries to load /opt/cisco/anyconnect/lib/libcurl.so.3 - resulting in “does not have the required support” (Cisco, you include a version of libcurl which does not work with your own product?) I’m curious why ldd does not show this:
# ldd /home/user/.cisco/hostscan/bin/cscan
        linux-gate.so.1 =>  (0xffffe000)
        libdl.so.2 => /lib/libdl.so.2 (0xf76bd000)
        libpthread.so.0 => /lib/libpthread.so.0 (0xf76a2000)
        libxml2.so.2 => /usr/lib/libxml2.so.2 (0xf7551000)
        libz.so.1 => /lib/libz.so.1 (0xf7538000)
        libm.so.6 => /lib/libm.so.6 (0xf750d000)
        libc.so.6 => /lib/libc.so.6 (0xf73a0000)
        /lib/ld-linux.so.2 (0xf76e9000)
  1. I don’t understand why the linker is linking to the 64bit lib when it is executing a 32bit binary. Tried to LD_PRELOAD the 32-bit one and LD_PRELOAD is not allowed. Does anyone have an idea on how to force it to find the (installed) 32bit version first?

This looks to be the same issue in: https://supportforums.cisco.com/thread/2145858 from April of this year - but no answers to that post.

Thanks for any tips on how to get this working.

Yeah, I tried that also - I finally gave up and used Yast to install “openconnect”, “NetworkManager-openconnect”,
and “NetworkManager-openconnect-kde4”. Switched my network card control from “traditional” to NetworkManager,
then simply added new “OpenConnect” session via the “VPN” tab on the NetworkManager tray icon. All you have to
supply is the remote server name, everyting else defaults. It’ll prompt for credentials when you connect via NetworkManager

Thanks for the openconnect suggestion. Unfortunately, that will not work for me as I need the Cisco Secure Desktop agent to run, and while openconnect supports this, it does not seem to be working well. I’m continuing that as an alternative line, but I’d also like to see if I can get anyconnect working as well.

Though I resolved the issue, I would like to understand better how the linking process is working.

The issue with the CSD binary not finding libcurl.so.4 was resolved by simply placing a copy of the 32-bit version in the anyconnect lib directory, which is searched as RPATH is set in the binary:

$readelf --dynamic /home/user/.cisco/hostscan/bin/cscan | grep RPATH
 0x0000000f (RPATH)                      Library rpath:  [/opt/cisco/anyconnect/lib:/opt/cisco/vpn/lib:/opt/cisco/hostscan/lib:~/.cisco/hostscan/lib]

cp  /usr/lib/libcurl.so.4 /opt/cisco/anyconnect/lib/libcurl.so.4

I’d like to understand what is going on with the linker and this binary though, as I still don’t get why the binary, when it needs libcurl, first finds a 32-bit version which lacks support:

 [/opt/cisco/anyconnect/lib/libcurl.so.3] does not have the required support

But then the linker tries to use the 64-bit version:

attempting to load library (/usr/lib64/libcurl.so.4) 
[Fri Oct 05 08:11:33.863 2012][cscan][warn][hs_dl_load_global] unable to load (/usr/lib64/libcurl.so.4): /usr/lib64/libcurl.so.4: wrong ELF class: ELFCLASS64

My questions are then:

Why is the linker trying /usr/lib64 before /usr/lib for a 32 bit binary?

What mechanism allow the binary to determine /opt/cisco/anyconnect/lib/libcurl.so.3 lacks the support it needs, and how does it then know to find a libcurl.so.4? (Does it just find the highest version of a shared library in the path used?)