$(MAKE) -C src clean | $(MAKE) -C src clean | ||||
install: | install: | ||||
cp src/libchat6.so /usr/local/lib/ | |||||
cp lib/libchat6.so /usr/local/lib/ | |||||
uninstall: | uninstall: | ||||
rm -f /usr/local/lib/libchat6.so | rm -f /usr/local/lib/libchat6.so | ||||
test: | test: | ||||
$(MAKE) -C src test | $(MAKE) -C src test | ||||
bootstrap: | |||||
$(MAKE) -C src bootstrap |
#ifndef LC6_BASE64_H | #ifndef LC6_BASE64_H | ||||
#define LC6_BASE64_H | #define LC6_BASE64_H | ||||
#include "../inc/lc6_common.h" | |||||
unsigned char* base64_encode(const unsigned char*, size_t, size_t*); | unsigned char* base64_encode(const unsigned char*, size_t, size_t*); | ||||
unsigned char* base64_decode(const unsigned char*, size_t, size_t*); | unsigned char* base64_decode(const unsigned char*, size_t, size_t*); | ||||
#ifndef LC6_COMMON_H | |||||
#define LC6_COMMON_H | |||||
#include <sys/param.h> | |||||
#include <arpa/inet.h> | |||||
#include "../inc/libchat6.h" | |||||
typedef struct LC6_NODE { | |||||
unsigned char *pub_key; | |||||
unsigned char *priv_key; | |||||
} LC6_NODE; | |||||
typedef struct LC6_USER { | |||||
struct LC6_USER *prev; | |||||
struct LC6_USER *next; | |||||
unsigned char nickname[256]; | |||||
unsigned char pub_key[32]; | |||||
unsigned char priv_key[32]; | |||||
unsigned char icon[32768]; | |||||
unsigned int status; | |||||
} LC6_USER; | |||||
#define LC6_CONFIG_BOOTSTRAP "bootstrap.bin" | |||||
#define LC6_CONFIG_USER "user.bin" | |||||
#define LC6_CONFIG_FRIENDS "friends.bin" | |||||
typedef struct LC6_BOOTSTRAP { | |||||
struct LC6_BOOTSTRAP *prev; | |||||
struct LC6_BOOTSTRAP *next; | |||||
time_t last_contact; | |||||
int af; | |||||
union addr { | |||||
struct in_addr inet; | |||||
struct in6_addr inet6; | |||||
} addr; | |||||
} LC6_BOOTSTRAP; | |||||
typedef struct LC6_CTX { | |||||
char path[MAXPATHLEN]; | |||||
LC6_USER *user; | |||||
LC6_USER *node; | |||||
LC6_USER *friends; | |||||
LC6_BOOTSTRAP *bootstrap; | |||||
} LC6_CTX; | |||||
#endif |
#ifndef LC6_CONFIG_H | |||||
#define LC6_CONFIG_H | |||||
#include "../inc/lc6_common.h" | |||||
LC6_CTX* lc6config_load(char *path, unsigned char *password); | |||||
int lc6config_save(LC6_CTX *conf, unsigned char *password); | |||||
void lc6config_free(LC6_CTX *conf); | |||||
void lc6config_load_file( | |||||
LC6_CTX *conf, | |||||
char *path, | |||||
char *filename, | |||||
unsigned char *password); | |||||
#endif |
#ifndef LC6_SSL_H | #ifndef LC6_SSL_H | ||||
#define LC6_SSL_H | #define LC6_SSL_H | ||||
#include "lc6_user.h" | |||||
#include "../inc/lc6_common.h" | |||||
int lc6crypto_public_encrypt( | int lc6crypto_public_encrypt( | ||||
const unsigned char *data, | const unsigned char *data, |
#ifndef LC6_HELPERS_H | #ifndef LC6_HELPERS_H | ||||
#define LC6_HELPERS_H | #define LC6_HELPERS_H | ||||
#include "../inc/lc6_common.h" | |||||
void lc6helpers_printhex(unsigned char*, int); | void lc6helpers_printhex(unsigned char*, int); | ||||
void lc6helpers_banner(unsigned char*); | void lc6helpers_banner(unsigned char*); | ||||
#ifndef LC6_NODE_H | #ifndef LC6_NODE_H | ||||
#define LC6_NODE_H | #define LC6_NODE_H | ||||
typedef struct LC6_NODE { | |||||
unsigned char *pub_key; | |||||
unsigned char *priv_key; | |||||
} LC6_NODE; | |||||
#include "../inc/lc6_common.h" | |||||
LC6_NODE* lc6node_create(void); | LC6_NODE* lc6node_create(void); | ||||
void lc6node_free(LC6_NODE *node); | void lc6node_free(LC6_NODE *node); |
#ifndef LC6_USER_H | |||||
#define LC6_USER_H | |||||
#include "../inc/lc6_common.h" | |||||
LC6_USER* lc6user_create(void); | |||||
void lc6user_free(LC6_CTX *conf, LC6_USER *user); | |||||
#endif |
#ifndef LC6_LIBCHAT6_H | |||||
#define LC6_LIBCHAT6_H | |||||
enum LIBCHAT_USER_STATUS { | |||||
LC6_STATUS_OFFLINE = 0, | |||||
LC6_STATUS_ONLINE, | |||||
LC6_STATUS_AWAY, | |||||
LC6_STATUS_TYPING | |||||
}; | |||||
typedef void *LIBCHAT; | |||||
LIBCHAT* libchat_init(char *path, unsigned char *password); | |||||
#endif |
LDFLAGS := | LDFLAGS := | ||||
LIBS := -lchat6 -lssl -lpthread -lcrypto -lsodium | LIBS := -lchat6 -lssl -lpthread -lcrypto -lsodium | ||||
TARGETS:= libchat6.so libchat6.a | |||||
BINDIR := ../bin | |||||
LIBDIR := ../lib | |||||
TARGETS:= $(LIBDIR)/libchat6.so $(LIBDIR)/libchat6.a | |||||
MAINS := $(.o, $(TARGETS) ) | MAINS := $(.o, $(TARGETS) ) | ||||
OBJ := \ | OBJ := \ | ||||
lc6_node.o \ | lc6_node.o \ | ||||
$(MAINS) | $(MAINS) | ||||
DEPS := | DEPS := | ||||
.PHONY: all clean | |||||
.PHONY: all clean install uninstall test | |||||
help: | |||||
@echo "make <all|clean|install|uninstall|test>" | |||||
all: $(TARGETS) | all: $(TARGETS) | ||||
clean: | clean: | ||||
rm -f $(TARGETS) $(OBJ) test test.o | |||||
rm -f $(TARGETS) $(OBJ) $(BINDIR)/test test.o | |||||
$(OBJ): %.o : %.c $(DEPS) | |||||
$(OBJ) : %.o : %.c | |||||
$(CC) $(CCFLAGS) $< -c -o $@ | $(CC) $(CCFLAGS) $< -c -o $@ | ||||
libchat6.so: $(OBJ) | |||||
$(LIBDIR)/libchat6.so: $(OBJ) | |||||
$(CC) $(LDFLAGS) -shared $^ $(LIBS) -o $@ | $(CC) $(LDFLAGS) -shared $^ $(LIBS) -o $@ | ||||
libchat6.a: $(OBJ) | |||||
$(LIBDIR)/libchat6.a: $(OBJ) | |||||
$(AR) rcs $@ $^ | $(AR) rcs $@ $^ | ||||
ranlib $@ | ranlib $@ | ||||
test: test.o | |||||
$(CC) $(CCFLAGS) $(LDFLAGS) $^ -o $@ $(LIBS) | |||||
bootstrap: bootstrap.o | |||||
$(CC) $(CCFLAGS) $(LDFLAGS) $^ -o $(BINDIR)/$@ $(LIBS) | |||||
test: test.o | |||||
$(CC) $(CCFLAGS) $(LDFLAGS) $^ -o $(BINDIR)/$@ $(LIBS) |
#include <stdio.h> | |||||
#include "../inc/lc6_config.h" | |||||
int main(int argc, char **argv) { | |||||
LC6_CTX *conf = NULL; | |||||
if ( argc == 2 ) { | |||||
conf = lc6config_load(argv[1], ""); | |||||
lc6config_save(conf, ""); | |||||
} | |||||
else { | |||||
fprintf(stderr,"Usage: %s <path to config dir>\n", argv[0]); | |||||
return -1; | |||||
} | |||||
return 0; | |||||
} |
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include "lc6_base64.h" | |||||
#include "../inc/lc6_base64.h" | |||||
static const unsigned char base64_table[65] = | static const unsigned char base64_table[65] = | ||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
#include <string.h> | #include <string.h> | ||||
#include <assert.h> | #include <assert.h> | ||||
#include "lc6_config.h" | |||||
#include "lc6_crypto.h" | |||||
#include "../inc/lc6_config.h" | |||||
#include "../inc/lc6_crypto.h" | |||||
LC6_CTX* lc6config_load(unsigned char *password, char *path) { | |||||
LC6_CTX* lc6config_load(char *path, unsigned char *password) { | |||||
LC6_CTX *conf; | LC6_CTX *conf; | ||||
conf = malloc(sizeof(LC6_CTX)); | conf = malloc(sizeof(LC6_CTX)); | ||||
if ( strcmp(filename, LC6_CONFIG_BOOTSTRAP) == 0 ) { | if ( strcmp(filename, LC6_CONFIG_BOOTSTRAP) == 0 ) { | ||||
LC6_BOOTSTRAP *prev = NULL; | LC6_BOOTSTRAP *prev = NULL; | ||||
LC6_BOOTSTRAP *chain = (LC6_BOOTSTRAP*)data; | |||||
int offset = 0; | int offset = 0; | ||||
conf->bootstrap = (LC6_BOOTSTRAP*)data; | conf->bootstrap = (LC6_BOOTSTRAP*)data; | ||||
while(offset<data_len/sizeof(LC6_BOOTSTRAP)) { | while(offset<data_len/sizeof(LC6_BOOTSTRAP)) { | ||||
LC6_BOOTSTRAP *node = conf->bootstrap + offset; | |||||
LC6_BOOTSTRAP *node = malloc(sizeof(LC6_BOOTSTRAP)); | |||||
assert(node); | |||||
memset(node, '\0', sizeof(LC6_BOOTSTRAP)); | |||||
memcpy(node, chain+offset, sizeof(LC6_BOOTSTRAP)); | |||||
if ( ! prev ) | |||||
conf->bootstrap = node; | |||||
else | |||||
prev->next = node; | |||||
node->prev = prev; | node->prev = prev; | ||||
node->next = NULL; | node->next = NULL; | ||||
node->prev->next = node; | |||||
prev = node; | prev = node; | ||||
offset++; | offset++; | ||||
} | } | ||||
else if ( strcmp(filename, LC6_CONFIG_FRIENDS) == 0 ) { | else if ( strcmp(filename, LC6_CONFIG_FRIENDS) == 0 ) { | ||||
LC6_USER *prev = NULL; | LC6_USER *prev = NULL; | ||||
LC6_USER *chain = (LC6_USER*)data; | |||||
int offset = 0; | int offset = 0; | ||||
conf->friends = (LC6_USER*)data; | |||||
while(offset<data_len/sizeof(LC6_USER)) { | while(offset<data_len/sizeof(LC6_USER)) { | ||||
LC6_USER *node = conf->friends + offset; | |||||
LC6_USER *node = malloc(sizeof(LC6_USER)); | |||||
assert(node); | |||||
memset(node, '\0', sizeof(LC6_USER)); | |||||
memcpy(node, chain+offset, sizeof(LC6_USER)); | |||||
if ( ! prev ) | |||||
conf->user = node; | |||||
else | |||||
prev->next = node; | |||||
node->prev = prev; | node->prev = prev; | ||||
node->next = NULL; | node->next = NULL; | ||||
node->prev->next = node; | |||||
prev = node; | prev = node; | ||||
offset++; | offset++; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
void lc6config_free(LC6_CTX *conf) { | |||||
} | |||||
int lc6config_save(LC6_CTX *conf, unsigned char *password) { | |||||
return 1; | |||||
} |
#ifndef LC6_CONFIG_H | |||||
#define LC6_CONFIG_H | |||||
#include <sys/param.h> | |||||
#include <arpa/inet.h> | |||||
#include "lc6_user.h" | |||||
#define LC6_CONFIG_BOOTSTRAP "bootstrap.bin" | |||||
#define LC6_CONFIG_USER "user.bin" | |||||
#define LC6_CONFIG_FRIENDS "friends.bin" | |||||
typedef struct LC6_BOOTSTRAP { | |||||
struct LC6_BOOTSTRAP *prev; | |||||
struct LC6_BOOTSTRAP *next; | |||||
time_t last_contact; | |||||
int af; | |||||
union addr { | |||||
struct in_addr inet; | |||||
struct in6_addr inet6; | |||||
} addr; | |||||
} LC6_BOOTSTRAP; | |||||
typedef struct LC6_CTX { | |||||
char path[MAXPATHLEN]; | |||||
LC6_USER *user; | |||||
LC6_USER *node; | |||||
LC6_USER *friends; | |||||
LC6_BOOTSTRAP *bootstrap; | |||||
} LC6_CTX; | |||||
LC6_CTX* lc6config_load(unsigned char *key, char *path); | |||||
void lc6config_load_file( | |||||
LC6_CTX *conf, | |||||
char *path, | |||||
char *filename, | |||||
unsigned char *password); | |||||
#endif |
#include <sodium.h> | #include <sodium.h> | ||||
#include <assert.h> | #include <assert.h> | ||||
#include "lc6_crypto.h" | |||||
#include "../inc/lc6_crypto.h" | |||||
int lc6crypto_seeded = 0; | int lc6crypto_seeded = 0; | ||||
LC6_USER* lc6crypto_genuserkey(LC6_USER *user) { | LC6_USER* lc6crypto_genuserkey(LC6_USER *user) { | ||||
assert(user); | assert(user); | ||||
user->pub_key = malloc(crypto_box_PUBLICKEYBYTES); | |||||
user->priv_key = malloc(crypto_box_SECRETKEYBYTES); | |||||
assert(user->pub_key); | |||||
assert(user->priv_key); | |||||
crypto_box_keypair(user->pub_key, user->priv_key); | crypto_box_keypair(user->pub_key, user->priv_key); | ||||
return user; | return user; | ||||
} | } |
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <assert.h> | #include <assert.h> | ||||
#include "lc6_crypto.h" | |||||
#include "lc6_node.h" | |||||
#include "../inc/lc6_crypto.h" | |||||
#include "../inc/lc6_node.h" | |||||
LC6_NODE* lc6node_create(void) { | LC6_NODE* lc6node_create(void) { | ||||
LC6_NODE *node; | LC6_NODE *node; | ||||
} | } | ||||
void lc6node_free(LC6_NODE *node) { | void lc6node_free(LC6_NODE *node) { | ||||
if ( !node ) | |||||
return; | |||||
if ( node->pub_key ) | |||||
free(node->pub_key); | |||||
if ( node->priv_key ) | |||||
free(node->priv_key); | |||||
free(node); | |||||
if ( node ) | |||||
free(node); | |||||
} | } |
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include "lc6_crypto.h" | |||||
#include "lc6_user.h" | |||||
#include "../inc/lc6_crypto.h" | |||||
#include "../inc/lc6_user.h" | |||||
#include "../inc/lc6_config.h" | |||||
LC6_USER* lc6user_create(void) { | LC6_USER* lc6user_create(void) { | ||||
LC6_USER *user = malloc(sizeof(LC6_USER)); | LC6_USER *user = malloc(sizeof(LC6_USER)); | ||||
return lc6crypto_genuserkey(user); | return lc6crypto_genuserkey(user); | ||||
} | } | ||||
void lc6user_free(LC6_USER *user) { | |||||
void lc6user_free(LC6_CTX *conf, LC6_USER *user) { | |||||
if ( !user ) | if ( !user ) | ||||
return; | return; | ||||
if ( user->pub_key ) | |||||
free(user->pub_key); | |||||
if ( user->priv_key ) | |||||
free(user->priv_key); | |||||
if ( user->icon ) | |||||
free(user->icon); | |||||
if ( user->next ) | if ( user->next ) | ||||
user->next->prev = user->prev; | user->next->prev = user->prev; | ||||
if ( user->prev ) | if ( user->prev ) | ||||
user->prev->next = user->next; | user->prev->next = user->next; | ||||
if ( conf->user == user ) | |||||
conf->user = user->next; | |||||
if ( conf->friends == user ) | |||||
conf->friends = user->next; | |||||
free(user); | free(user); | ||||
} | } |
#ifndef LC6_USER_H | |||||
#define LC6_USER_H | |||||
typedef struct LC6_USER { | |||||
struct LC6_USER *prev; | |||||
struct LC6_USER *next; | |||||
unsigned char nickname[256]; | |||||
unsigned char *pub_key; | |||||
unsigned char *priv_key; | |||||
unsigned char *icon; | |||||
unsigned int status; | |||||
} LC6_USER; | |||||
LC6_USER* lc6user_create(void); | |||||
void lc6user_free(LC6_USER *user); | |||||
#endif |
#include <string.h> | #include <string.h> | ||||
#include <assert.h> | #include <assert.h> | ||||
#include "lc6_config.h" | |||||
#include "../inc/lc6_config.h" | |||||
#include "../inc/lc6_user.h" | |||||
LC6_CTX* libchat_init(unsigned char *password, char *path) { | |||||
LIBCHAT* libchat_init(char *path, unsigned char *password) { | |||||
LC6_CTX *conf = lc6config_load(password, path); | |||||
LC6_CTX *conf = lc6config_load(path, password); | |||||
if ( !conf ) | if ( !conf ) | ||||
return NULL; | return NULL; | ||||
if ( !conf->user ) | if ( !conf->user ) | ||||
conf->user = lc6user_create(); | conf->user = lc6user_create(); | ||||
return conf; | |||||
return (LIBCHAT*)conf; | |||||
} | } | ||||
#ifndef LC6_LIBCHAT6_H | |||||
#define LC6_LIBCHAT6_H | |||||
enum LIBCHAR_USER_STATUS { | |||||
LC6_STATUS_OFFLINE = 0, | |||||
LC6_STATUS_ONLINE, | |||||
LC6_STATUS_AWAY, | |||||
LC6_STATUS_TYPING | |||||
}; | |||||
typedef void *LIBCHAT; | |||||
LIBCHAT* libchat_init(unsigned char *password, char *path); | |||||
#endif |
#include <sodium.h> | #include <sodium.h> | ||||
#include "libchat6.h" | |||||
#include "../inc/libchat6.h" | |||||
#include "lc6_helpers.h" | |||||
#include "lc6_crypto.h" | |||||
#include "lc6_user.h" | |||||
#include "../inc/lc6_helpers.h" | |||||
#include "../inc/lc6_crypto.h" | |||||
#include "../inc/lc6_user.h" | |||||
int main(int argc, char **argv) { | int main(int argc, char **argv) { | ||||
free(ptr_nonce); | free(ptr_nonce); | ||||
free(ptr_data2); | free(ptr_data2); | ||||
lc6user_free(user); | |||||
lc6user_free(NULL, user); | |||||
user = NULL; | user = NULL; | ||||
return 0; | return 0; |