Jacob Krieg
Jacob Krieg

Reputation: 3174

Undefined symbols for architecture i386 for OpenSSL library

I'm reading this book Network Security with OpenSSL by Pravir Chandra, Matt Messier and John Viega and I'm trying to create an SSL client/server connection after their example in the book using OpenSSL but I get this error and I don't know why.

This is my server:

#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/ssl.h>
#include <openssl/x509v3.h>

#include <pthread.h>

#define PORT            "6001"
#define SERVER          "splat.zork.org"
#define CLIENT          "shell.zork.org"

void handle_error(const char *file, int lineno, const char *msg)
{
    fprintf(stderr, "** %s:%i %s\n", file, lineno, msg);
    ERR_print_errors_fp(stderr);
    exit(-1);
}

void init_OpenSSL(void)
{
    if (!THREAD_setup() || !SSL_library_init())
    {
        fprintf(stderr, "** OpenSSL initialization failed!\n");
        exit(-1);
    }
    SSL_load_error_strings();
}


void do_server_loop(BIO *conn)
{
    int  done, err, nread;
    char buf[80];

    do
    {
        for (nread = 0;  nread < sizeof(buf);  nread += err)
        {
             err = BIO_read(conn, buf + nread, sizeof(buf) - nread);
             if (err <= 0)
                 break;
        }
        fwrite(buf, 1, nread, stdout);
    }
    while (err > 0);
}

void *server_thread(void *arg)
{
    BIO *client = (BIO *)arg;

    pthread_detach(pthread_self(  ));

    fprintf(stderr, "Connection opened.\n");
    do_server_loop(client);
    fprintf(stderr, "Connection closed.\n");

    BIO_free(client);
    ERR_remove_state(0);
}

int main(int argc, char *argv[])
{
    BIO *acc, *client;

    pthread_t tid;

    init_OpenSSL();

    acc = BIO_new_accept(PORT);
    if (!acc)
        handle_error(__FILE__, __LINE__, "Error creating server socket");

    if (BIO_do_accept(acc) <= 0)
        handle_error(__FILE__, __LINE__, "Error binding server socket");

    for (;;)
    {
        if (BIO_do_accept(acc) <= 0)
            handle_error(__FILE__, __LINE__, "Error accepting connection");

        client = BIO_pop(acc);
        pthread_create(&tid, NULL, server_thread, client);
    }

    BIO_free(acc);
    return 0;
}

I'm compiling the source using gcc:

$ gcc -o server server.c -lssl -crypto -lpthread -lm
Undefined symbols for architecture i386:
  "_ERR_print_errors_fp", referenced from:
      _handle_error in ccgAll3d.o
  "_THREAD_setup", referenced from:
      _init_OpenSSL in ccgAll3d.o
  "_BIO_read", referenced from:
      _do_server_loop in ccgAll3d.o
  "_BIO_free", referenced from:
      _server_thread in ccgAll3d.o
  "_ERR_remove_state", referenced from:
      _server_thread in ccgAll3d.o
  "_BIO_new_accept", referenced from:
      _main in ccgAll3d.o
  "_BIO_ctrl", referenced from:
      _main in ccgAll3d.o
  "_BIO_pop", referenced from:
      _main in ccgAll3d.o
ld: symbol(s) not found for architecture i386
collect2: ld returned 1 exit status

Can anyone tell me why is this happening?

I got something similar some time ago and solved it by defining the functions that were problematic but this doesn't work anymore.

I'm compiling the source on a Mac OS X 10.6.8. Is it because I'm using a 32-bit system?

This is the command I'm compiling with gcc -Wall -lssl -crypto -lpthread -lm -o server server.c

Upvotes: 4

Views: 3747

Answers (2)

Anton Kovalenko
Anton Kovalenko

Reputation: 21507

You'll be a little closer with gcc -o server sslserver.c -pthread -lssl.

Also the book's errata inform us that SSL_init_library should be SSL_library_init.

The only undefined reference left is 'THREAD_setup'.

Upvotes: 4

Patrick B.
Patrick B.

Reputation: 12353

You seem not to link with the openssl-library. Try to add

[..] -lssl [..]

in addition to your other libraries when linking.

Your gcc-line seems incomplete as well:

 gcc -o -lpthread -lm server.c 

The -o argument should be followed by a output-filename (in this case it will use "-lpthread" as filename.

Upvotes: 1

Related Questions