From: Saverio Proto Date: Thu, 3 Apr 2014 14:01:29 +0000 (+0200) Subject: Successfully compile the libmeshlink library with autotools and compile the sample... X-Git-Url: http://git.meshlink.io/?p=meshlink;a=commitdiff_plain;h=3113556aba931142a93384ebd9ba43c842761561 Successfully compile the libmeshlink library with autotools and compile the sample application against it. Some code from tincctl was copied to libmeshlink.c to avoid redefinition of main in tincctl.c --- diff --git a/src/Makefile.am b/src/Makefile.am index 31dfae5e..ad60f454 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -104,17 +104,74 @@ sptps_speed_SOURCES = \ lib_LTLIBRARIES = libmeshlink.la libmeshlink_la_SOURCES = \ - libmeshlink.c libmeshlink.h + libmeshlink.c libmeshlink.h \ + buffer.c buffer.h \ + cipher.h \ + conf.c conf.h \ + connection.c connection.h \ + control.c control.h \ + control_common.h \ + crypto.h \ + device.h \ + digest.h \ + dropin.c dropin.h \ + dummy_device.c \ + ecdh.h \ + ecdsa.h \ + ecdsagen.h \ + edge.c edge.h \ + ethernet.h \ + event.c event.h \ + fake-gai-errnos.h \ + fake-getaddrinfo.c fake-getaddrinfo.h \ + fake-getnameinfo.c fake-getnameinfo.h \ + getopt.c getopt.h \ + getopt1.c \ + graph.c graph.h \ + hash.c hash.h \ + have.h \ + ipv4.h \ + ipv6.h \ + list.c list.h \ + logger.c logger.h \ + meta.c meta.h \ + multicast_device.c \ + names.c names.h \ + net.c net.h \ + net_packet.c \ + net_setup.c \ + net_socket.c \ + netutl.c netutl.h \ + node.c node.h \ + prf.h \ + process.c process.h \ + protocol.c protocol.h \ + protocol_auth.c \ + protocol_edge.c \ + protocol_key.c \ + protocol_misc.c \ + protocol_subnet.c \ + raw_socket_device.c \ + route.c route.h \ + rsa.h \ + rsagen.h \ + script.c script.h \ + splay_tree.c splay_tree.h \ + sptps.c sptps.h \ + subnet.c subnet.h \ + subnet_parse.c \ + system.h \ + tincd.c \ + utils.c utils.h \ + xalloc.h libmeshlink_la_CFLAGS = -fPIC -libmeshlink_la_LIBADD = \ - protocol.o protocol_auth.o - ## Conditionally compile device drivers if LINUX tincd_SOURCES += linux/device.c +libmeshlink_la_SOURCES +=linux/device.c endif if BSD @@ -163,6 +220,16 @@ tinc_SOURCES += \ openssl/prf.c \ openssl/rsa.c \ openssl/rsagen.c +libmeshlink_la_SOURCES += \ + openssl/cipher.c \ + openssl/crypto.c \ + openssl/digest.c openssl/digest.h \ + openssl/ecdh.c \ + openssl/ecdsa.c \ + openssl/ecdsagen.c \ + openssl/prf.c \ + openssl/rsa.c \ + openssl/rsagen.c sptps_test_SOURCES += \ openssl/cipher.c \ openssl/crypto.c \ diff --git a/src/libmeshlink.c b/src/libmeshlink.c index 04e31415..c05d1781 100644 --- a/src/libmeshlink.c +++ b/src/libmeshlink.c @@ -18,7 +18,180 @@ */ #include "libmeshlink.h" +#include "crypto.h" +#include "ecdsagen.h" +char *hosts_dir = NULL; +static char *name = NULL; + +/* + Generate a public/private ECDSA keypair, and ask for a file to store + them in. +*/ +bool ecdsa_keygen(bool ask) { + ecdsa_t *key; + FILE *f; + char *pubname, *privname; + + fprintf(stderr, "Generating ECDSA keypair:\n"); + + if(!(key = ecdsa_generate())) { + fprintf(stderr, "Error during key generation!\n"); + return false; + } else + fprintf(stderr, "Done.\n"); + + xasprintf(&privname, "%s" SLASH "ecdsa_key.priv", confbase); + //f = ask_and_open(privname, "private ECDSA key", "a", ask, 0600); //this function is not ported to lib because makes no sense + free(privname); + + if(!f) + return false; + + if(!ecdsa_write_pem_private_key(key, f)) { + fprintf(stderr, "Error writing private key!\n"); + ecdsa_free(key); + fclose(f); + return false; + } + + fclose(f); + + if(name) + xasprintf(&pubname, "%s" SLASH "hosts" SLASH "%s", confbase, name); + else + xasprintf(&pubname, "%s" SLASH "ecdsa_key.pub", confbase); + + //f = ask_and_open(pubname, "public ECDSA key", "a", ask, 0666); + free(pubname); + + if(!f) + return false; + + char *pubkey = ecdsa_get_base64_public_key(key); + fprintf(f, "ECDSAPublicKey = %s\n", pubkey); + free(pubkey); + + fclose(f); + ecdsa_free(key); + + return true; +} + +/* + Generate a public/private RSA keypair, and ask for a file to store + them in. +*/ +bool rsa_keygen(int bits, bool ask) { + rsa_t *key; + FILE *f; + char *pubname, *privname; + + fprintf(stderr, "Generating %d bits keys:\n", bits); + + if(!(key = rsa_generate(bits, 0x10001))) { + fprintf(stderr, "Error during key generation!\n"); + return false; + } else + fprintf(stderr, "Done.\n"); + + xasprintf(&privname, "%s" SLASH "rsa_key.priv", confbase); + //f = ask_and_open(privname, "private RSA key", "a", ask, 0600); + free(privname); + + if(!f) + return false; + + if(!rsa_write_pem_private_key(key, f)) { + fprintf(stderr, "Error writing private key!\n"); + fclose(f); + rsa_free(key); + return false; + } + + fclose(f); + + if(name) + xasprintf(&pubname, "%s" SLASH "hosts" SLASH "%s", confbase, name); + else + xasprintf(&pubname, "%s" SLASH "rsa_key.pub", confbase); + + //f = ask_and_open(pubname, "public RSA key", "a", ask, 0666); + free(pubname); + + if(!f) + return false; + + if(!rsa_write_pem_public_key(key, f)) { + fprintf(stderr, "Error writing public key!\n"); + fclose(f); + rsa_free(key); + return false; + } + + fclose(f); + rsa_free(key); + + return true; +} + +static bool try_bind(int port) { + struct addrinfo *ai = NULL; + struct addrinfo hint = { + .ai_flags = AI_PASSIVE, + .ai_family = AF_UNSPEC, + .ai_socktype = SOCK_STREAM, + .ai_protocol = IPPROTO_TCP, + }; + + char portstr[16]; + snprintf(portstr, sizeof portstr, "%d", port); + + if(getaddrinfo(NULL, portstr, &hint, &ai) || !ai) + return false; + + while(ai) { + int fd = socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP); + if(!fd) + return false; + int result = bind(fd, ai->ai_addr, ai->ai_addrlen); + closesocket(fd); + if(result) + return false; + ai = ai->ai_next; + } + + return true; +} + +int check_port(char *name) { + if(try_bind(655)) + return 655; + + fprintf(stderr, "Warning: could not bind to port 655. "); + + for(int i = 0; i < 100; i++) { + int port = 0x1000 + (rand() & 0x7fff); + if(try_bind(port)) { + char *filename; + xasprintf(&filename, "%s" SLASH "hosts" SLASH "%s", confbase, name); + FILE *f = fopen(filename, "a"); + free(filename); + if(!f) { + fprintf(stderr, "Please change tinc's Port manually.\n"); + return 0; + } + + fprintf(f, "Port = %d\n", port); + fclose(f); + fprintf(stderr, "Tinc will instead listen on port %d.\n", port); + return port; + } + } + + fprintf(stderr, "Please change tinc's Port manually.\n"); + return 0; +} //tinc_setup() should basically do what cmd_init() from src/tincctl.c does, except it doesn't have to generate a tinc-up script. bool tinc_setup(const char* tinc_conf, const char* name) { if(!access(tinc_conf, F_OK)) { diff --git a/src/libmeshlink.h b/src/libmeshlink.h index f97050b5..02a94484 100644 --- a/src/libmeshlink.h +++ b/src/libmeshlink.h @@ -20,8 +20,12 @@ #include "system.h" #include "node.h" #include "names.h" -#include "tincctl.h" +//#include "tincctl.h" +#include "xalloc.h" +extern char *hosts_dir; + +extern int check_port(char *name); /* OLD: tinc_configuration_t provides all information required to setup "/etc/tinc" I think tinc_setup() should basically do what cmd_init() from src/tincctl.c does, except it doesn't have to generate a tinc-up script. */