Debugging modified OpenSSL - c

I would like to modify OpenSSL code and then debug it in my IDE (QTCreator).
I have downloaded the OpenSSL source code, built it according to ./config with debugging symbols, and deployed it in non-system folder. Still, when I make modifications to the library, the changes are not effective in the debugged program.
For instance, I attempt to modify handshake process and test the results using the s_client app. Nevertheless, the s_client app points to the system version of OpenSSL. Namely, s_client includes <openssl/...> (which is located in /usr/local/...).
I would like it to point to the just installed/modified version of openssl in different folder. There's a catch though. I have figured only one way how to do it, by modifying the original OpenSSL makefile, which is just huge and the task seems overwhelming.
Does anyone has any idea how to approach this issue? Please note that I would like to keep the system version of the OpenSSL operational (symbolic link not suitable).
I run the Ubuntu 16.04 LTS. The output of ldd /my/version/of/openssl is
linux-vdso.so.1 => (0x00007ffd9a3d6000)
libssl.so.1.1 => /usr/local/lib/libssl.so.1.1 (0x00007f04523f8000)
libcrypto.so.1.1 => /usr/local/lib/libcrypto.so.1.1 (0x00007f0451f6a000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f0451d4d000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0451983000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f045177f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0452668000)

With the help of the two guys (see comments), I was able to figure out the problem. First, make sure you compile OpenSSL with --prefix and --openssl directories properly set.
Once OpenSSL installed, you need your code (apps of OpenSSL) to be calling/linking your new version of OpenSSL. In QtCreator you can achieve this by setting the LD_LIBRARY_PATH to the directory with the library files libcrypto.so.1 and libssl.so.1. The setting is done in Projects -> Run environment -> (add LD_LIBRARY_PATH into system environment).
Moreover, you can check what libraries are called by the binary manually, by entering the directory with the binary and calling command ldd ./openssl from the terminal. This way, you will see what libraries are called (it should be your own version, not the system libraries). Further, you can set LD_LIBRARY_PATH from terminal, optionally with export command in front of it, to achieve permanent effect (lasting whole terminal session). In total, you could call
export LD_LIBRARY_PATH=/path/to/your/lib.

Related

Does curl need openssl at runtime?

Curl lists openSSL as an external dependency on https://curl.se/docs/libs.html.
However, if I do otool -L $(which curl) (macOS 12.5) I get the following output:
/usr/bin/curl:
/usr/lib/libcurl.4.dylib (compatibility version 7.0.0, current version 9.0.0)
/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.120.1)
No openSSL. Is this because it is only needed to compile/build curl but is not needed as an external library at runtime?
Will curl still work if I delete openSSL?
If your curl knows how to speak HTTPS or any other protocol that needs TLS, then your curl depends on a TLS library.
OpenSSL is one such a library, but curl currently supports 13 different TLS libraries that it can be built to use.
If your curl speaks a TLS protocol, it depends on one of those supported libraries. On macOS, Apple seems to have favored libressl lately but in the past they also made builds using Secure Transport directly.
The curl -V output shows which TLS library it uses in the first line, but it might take a little experience to fully understand it. TLS libraries mentioned within parentheses there are optionally enabled by the application at start.
The libraries showed in the otool output are dynamically linked at run-time. It means they need to be present and loadable when you invoke curl so that the run-time linker can load them and execute curl fine.
If you build curl yourself or download someone else's build, you can also link it statically and then all the libraries can be built into a single huge binary blob, but that is not how curl is usually built and shipped in operating systems like macOS and Linux distributions.

Location of time.h -> localtime() implemenation in Ubuntu?

I am searching for the implementation of localtime() function in time.h. I see that different platforms have different locations for source of c library. I wanted to know the location in Ubuntu 14.04? If by default source is not included in OS, please let me know how to download source or online location of the source.
Thanks.
Check which binary your system uses as libc implementation.
To do so compile a minimal C program and run ldd on it:
ldd a.out
You might get something like this:
linux-vdso.so.1 => (0x00007fff429c6000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f21cdcb7000)
/lib64/ld-linux-x86-64.so.2 (0x00007f21ce05e000)
From this you can pull the info libc is proided by libc6.so.6.
Check which package provides this binary.
Search the package providing the file found under 1.:
dpkg -S libc.so.6
You might get:
libc6-i386: /lib32/libc.so.6
libc6:amd64: /lib/x86_64-linux-gnu/libc.so.6
The above output tells you, that there are two packages providing the file. Here it's the 32 bit and 64 bit implementation.
Decide which one you want and do apt-get source this package's sources.
Assuming the package would be libc6, do
apt-get source libc6
and find thre source in a directory inside the current directory.

How to compile curl with latest openssl

I download curl7.40 source code, and I have already compile openssl
1.0.2 source code, Now I want to compile curl with openssl 1.0.2.
./configure --prefix=/usr/local/curl-7.40.0 --with-ssl
--with-libssl-prefix=/usr/local/openssl-1.0.2
make && make install
After I install, I ldd curl library but still link with system default library.
ldd libcurl.so
linux-vdso.so.1 => (0x00007fff2db2e000)
libidn.so.11 => /usr/lib/x86_64-linux-gnu/libidn.so.11 (0x00007fafb9b6e000)
librtmp.so.0 => /usr/lib/x86_64-linux-gnu/librtmp.so.0 (0x00007fafb9954000)
libssl.so.1.0.0 => /lib/x86_64-linux-gnu/libssl.so.1.0.0 (0x00007fafb96f5000)
libcrypto.so.1.0.0 => /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
(0x00007fafb931b000)
...
UPDATE
After some search, I use below command to config.
./configure --prefix=/usr/local/curl-7.40.0 --with-ssl=/usr/local/openssl-1.0.2
But when make install, it will show below error information.
../lib/.libs/libcurl.so: undefined reference to `SSLv2_client_method'
collect2: error: ld returned 1 exit status
The problem is likely with how you have build the OpenSSL library.
It is likely you have built openssl with SSLv2 disabled as some distributions have SSLv2 disable by default. Look at the ./config for your system when you are compiling OpenSSL, and find the option that controls the OPENSSL_NO_SSL2 preprocessor flag.
In order to use proper version of openssl while making from source, you can make openssl like this:
cd <path-to-openssl-dir>
./config enable-ssl2 enable-ssl3 --prefix=<path-to-openssl-install-dir>
Then, you can link your curl version properly to openssl by:
./configure --with-ssl=<path-to-openssl-install-dir>
SSLv2_client_method() is used in lib/vtls/openssl.c, line 1575 with a check for availability of this function via autoconf. It seems to me that autoconf's AC_CHECK_FUNCS incorrectly finds your system installation of openssl which has SSLv2 enabled before #includeing your own installation of openssl-1.0.2 which doesn't have SSLv2_client_method() and thus assumes the function to be available.
Try passing CFLAGS=-I/usr/local/openssl-1.0.2/include or even "CFLAGS=-I/usr/local/openssl-1.0.2/include -DOPENSSL_NO_SSL2" as arguments to ./configure to force openssl.c to make do without the SSLv2_client_method() incorrectly assumed to be available.

How to compile readline from source?

When I compile readline into my directory /mypath as instructed (./configure --prefix=/mypath; make; make install) I get the following unresolved symbols in it:
ldd -r /mypath/lib/libreadline.so.6.2
linux-vdso.so.1 => (0x00007ffffb186000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f450c62f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f450cc07000)
undefined symbol: UP (/mypath/lib/libreadline.so.6.2)
undefined symbol: PC (/mypath/lib/libreadline.so.6.2)
undefined symbol: BC (/mypath/lib/libreadline.so.6.2)
When I read the readme-file of readline, this seems to be a feature and not a bug:
`--with-curses'
This tells readline that it can find the termcap library functions
(tgetent, et al.) in the curses library, rather than a separate
termcap library. Readline uses the termcap functions, but does not
link with the termcap or curses library itself, allowing applications
which link with readline the to choose an appropriate library.
This option tells readline to link the example programs with the
curses library rather than libtermcap.
I tried it of course with --with-curses but that did not change anything, which is not surprising because it seems to be a setting that only affects some testing programs in readline.
My distribution (debian) however has a readline without undefined symbols, so it is clearly possible to do.
How to create a readline library without unresolved symbols?
Edit:
I have compiled and installed ncurses into the same directory and I have also tried to configure readline with CFLAGS=" -Wl,-rpath=/mypath" and --enable-static, without success.
Those symbols are defined by libncurses, I think. You can probably confirm this like this:
env LD_PRELOAD=/usr/lib/libncurses.so ldd -r /mypath/lib/libreadline.so.6.2
(I think ldd takes preloads into account when checking symbols, but it may not.)
The build script used by Arch Linux is here. It looks like the trick is to use:
make SHLIB_LIBS=/mypath/libncurses.so
There's also some other adjustments to the -rpath options in a build file, so you might need that also.
The make install step is installing the shared library in some directory, often /usr/local/lib/
You need to make the dynamic loader ld.so(8) aware of that. I would suggest add once /usr/local/lib/ into your /etc/ld.so.conf file then running ldconfig after each installation of new shared libraries inside it. See ldconfig(8), ldd(1)
You could also specify some -Wl,-rpath when linking programs with your version of libreadline.so
And when building a shared library you can link it to other shared libraries. On my Debian the system libreadline is linked to libtinfo:
% ldd /lib/x86_64-linux-gnu/libreadline.so.6
linux-vdso.so.1 (0x00007ffffccf3000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f45cffcc000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f45cfc23000)
/lib64/ld-linux-x86-64.so.2 (0x00007f45d046c000)
You may want to study the source package of your readline6, since it contains the patches to the building procedure.
BTW, my Debian has a libtinfo5 package (obtained with dpkg -S /lib/x86_64-linux-gnu/libtinfo.so.5)

eglibc-2.11.3: where is libc-2.11.3.so? Not there after compilation

I compiled eglibc-2.11.3 on Debian squeeze, but do not see the libc-2.11.3.so. I believe that this is symlinked to from libc.so.6.
Not a c expert, so bear with me. These are the steps I took according to the included install file plus debian patch:
apt-get source libc6 # gets me eglibc-2.11.3
In build directory:
../configure --prefix=/usr
make -f ../debian/rules patch
make
I didn't see any errors before it gave me back the prompt, am I missing something?
do not see the libc-2.11.3.so
The library is linked as libc.so.6 (should be in the directory in which you executed make).
make install is what should create libc-2.11.3.so and a symlink libc.so.6 in the installation directory.
You may want to try make install PREFIX=/tmp/glibc-install and examine the resulting install tree, to make sure everything is where you expect it.
In debian/quiltrc change
QUILT_PATCH_OPTS="--unified-reject-files"
to become
QUILT_PATCH_OPTS="--reject-format=unified"

Resources