Compare commits
5 Commits
722baa7da3
...
c468363efb
Author | SHA1 | Date |
---|---|---|
Alexander Andreev | c468363efb | |
Alexander Andreev | c8d69f23bc | |
Alexander Andreev | 9e9b0ba047 | |
Alexander Andreev | de1d4085b9 | |
Alexander Andreev | 5e45b95fdf |
2
Makefile
2
Makefile
|
@ -12,7 +12,7 @@ OBJ_DIR := obj
|
||||||
SRCs := $(wildcard $(SRC_DIR)/*.c)
|
SRCs := $(wildcard $(SRC_DIR)/*.c)
|
||||||
OBJs := $(SRCs:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
|
OBJs := $(SRCs:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
|
||||||
|
|
||||||
CFLAGS = --std=c99 -D_POSIX_C_SOURCE=200112L -O3 -Wall -Werror -Wextra -pedantic
|
CFLAGS = --std=c99 -D_POSIX_C_SOURCE=200809L -O3 -Wall -Werror -Wextra -pedantic
|
||||||
CFLAGS += -flto
|
CFLAGS += -flto
|
||||||
LDFLAGS += -lportaudio -lopus -lsodium
|
LDFLAGS += -lportaudio -lopus -lsodium
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "addrbook.h"
|
||||||
|
#include "crypt.h"
|
||||||
|
|
||||||
|
#define ADDRBOOK_DELIM_COUNT 4
|
||||||
|
|
||||||
|
char *addrbook_entry_to_string(const addrbook_entry_t *const ent) {
|
||||||
|
size_t str_len = CRYPT_PKEY_HEXLEN + ent->name_len + ent->last_addr_len
|
||||||
|
+ ent->last_port_len + ADDRBOOK_DELIM_COUNT;
|
||||||
|
char *str = (char *)malloc(str_len * sizeof(char));
|
||||||
|
sprintf(str, "%.128s\t%.*s\t%.*s\t%.*s\n", ent->pubk, ent->name_len, ent->name,
|
||||||
|
ent->last_addr_len, ent->last_addr, ent->last_port_len, ent->last_port);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
int addrbook_entry_from_string(addrbook_entry_t *const ent, char * str) {
|
||||||
|
char *tok = strtok(str, "\t\n");
|
||||||
|
if (tok == NULL)
|
||||||
|
return -1;
|
||||||
|
memcpy(ent->pubk, tok, CRYPT_PKEY_HEXLEN);
|
||||||
|
|
||||||
|
tok = strtok(NULL, "\t\n");
|
||||||
|
ent->name = strdup(tok);
|
||||||
|
ent->name_len = strlen(ent->name);
|
||||||
|
|
||||||
|
tok = strtok(NULL, "\t\n");
|
||||||
|
ent->last_addr = strdup(tok);
|
||||||
|
ent->last_addr_len = strlen(ent->last_addr);
|
||||||
|
|
||||||
|
tok = strtok(NULL, "\t\n");
|
||||||
|
ent->last_port = strdup(tok);
|
||||||
|
ent->last_port_len = strlen(ent->last_port);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int addrbook_init(addrbook_t *const ab) {
|
||||||
|
ab->entries = (addrbook_entry_t *)malloc(sizeof(addrbook_entry_t));
|
||||||
|
if (ab->entries == NULL)
|
||||||
|
return -1;
|
||||||
|
ab->entries_len = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addrbook_destroy(addrbook_t *const ab) {
|
||||||
|
free(ab->entries);
|
||||||
|
ab->entries_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int addrbook_load(addrbook_t *ab, FILE *in) {
|
||||||
|
char *line = NULL;
|
||||||
|
size_t line_len = 0;
|
||||||
|
size_t lines = 0;
|
||||||
|
|
||||||
|
while (getline(&line, &line_len, in) != -1)
|
||||||
|
++lines;
|
||||||
|
|
||||||
|
if (ab->entries != NULL)
|
||||||
|
free(ab->entries);
|
||||||
|
ab->entries = (addrbook_entry_t *)malloc(lines * sizeof(addrbook_entry_t));
|
||||||
|
if (ab->entries == NULL)
|
||||||
|
return -1;
|
||||||
|
ab->entries_len = 0;
|
||||||
|
|
||||||
|
fseek(in, 0, SEEK_SET);
|
||||||
|
|
||||||
|
addrbook_entry_t ent;
|
||||||
|
|
||||||
|
while (getline(&line, &line_len, in) != -1) {
|
||||||
|
if (addrbook_entry_from_string(&ent, line) == -1) {
|
||||||
|
addrbook_destroy(ab);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addrbook_add(ab, &ent) == -1) {
|
||||||
|
addrbook_destroy(ab);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int addrbook_store(addrbook_t *ab, FILE *out) {
|
||||||
|
for (size_t i = 0; i < ab->entries_len; ++i) {
|
||||||
|
char *ent_str = addrbook_entry_to_string(&ab->entries[i]);
|
||||||
|
fputs(ent_str, out);
|
||||||
|
free(ent_str);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int addrbook_add(addrbook_t *const ab, const addrbook_entry_t *const ent) {
|
||||||
|
if (addrbook_get(ab, ent->pubk) != NULL)
|
||||||
|
return -1;
|
||||||
|
if (ab->entries_len > 0)
|
||||||
|
ab->entries = realloc(ab->entries, ++ab->entries_len);
|
||||||
|
else
|
||||||
|
++ab->entries_len;
|
||||||
|
ab->entries[ab->entries_len-1] = *ent;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
addrbook_entry_t *addrbook_get(const addrbook_t *const ab, const char pkey[CRYPT_PKEY_HEXLEN]) {
|
||||||
|
for (size_t i = 0; i < ab->entries_len; ++i)
|
||||||
|
if (strncmp(ab->entries[i].pubk, pkey, CRYPT_PKEY_HEXLEN) == 0)
|
||||||
|
return &ab->entries[i];
|
||||||
|
return NULL;
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
#ifndef _ADDRBOOK_H_
|
||||||
|
#define _ADDRBOOK_H_
|
||||||
|
|
||||||
|
#include "crypt.h"
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#define ADDRBOOK_NAME_MAXLEN 64
|
||||||
|
#define ADDRBOOK_PORT_MAXLEN 5
|
||||||
|
|
||||||
|
typedef struct addrbook_entry_t {
|
||||||
|
char pubk[CRYPT_PKEY_HEXLEN];
|
||||||
|
char *name;
|
||||||
|
char *last_addr;
|
||||||
|
char *last_port;
|
||||||
|
unsigned char name_len;
|
||||||
|
unsigned char last_addr_len;
|
||||||
|
unsigned char last_port_len;
|
||||||
|
} addrbook_entry_t;
|
||||||
|
|
||||||
|
char *addrbook_entry_to_string(const addrbook_entry_t *const ent);
|
||||||
|
int addrbook_entry_from_string(addrbook_entry_t *const ent, char * str);
|
||||||
|
|
||||||
|
typedef struct addrbook_t {
|
||||||
|
addrbook_entry_t *entries;
|
||||||
|
size_t entries_len;
|
||||||
|
} addrbook_t;
|
||||||
|
|
||||||
|
int addrbook_init(addrbook_t *const ab);
|
||||||
|
void addrbook_destroy(addrbook_t *const ab);
|
||||||
|
|
||||||
|
int addrbook_load(addrbook_t *ab, FILE *in);
|
||||||
|
int addrbook_store(addrbook_t *ab, FILE *out);
|
||||||
|
|
||||||
|
int addrbook_add(addrbook_t *const ab, const addrbook_entry_t *const ent);
|
||||||
|
addrbook_entry_t *addrbook_get(const addrbook_t *const ab, const char pkey[CRYPT_PKEY_HEXLEN]);
|
||||||
|
|
||||||
|
#endif /* _ADDRBOOK_H_ */
|
145
src/main.c
145
src/main.c
|
@ -1,14 +1,9 @@
|
||||||
#include <portaudio.h>
|
|
||||||
#include <sodium/core.h>
|
|
||||||
#include <sodium/crypto_box.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
// #include "audio.h"
|
// #include "audio.h"
|
||||||
|
#include "addrbook.h"
|
||||||
#include "crypt.h"
|
#include "crypt.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#define CHANNELS 1
|
#define CHANNELS 1
|
||||||
#define SAMPLE_RATE 48000
|
#define SAMPLE_RATE 48000
|
||||||
|
@ -25,7 +20,20 @@ void usage(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
int ret = 0;
|
|
||||||
|
addrbook_t ab = {0};
|
||||||
|
|
||||||
|
FILE *in = fopen("addressbook_key", "r");
|
||||||
|
|
||||||
|
addrbook_load(&ab, in);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < ab.entries_len; ++i)
|
||||||
|
printf("%ld: %.128s %s %s %s\n", i, ab.entries[i].pubk, ab.entries[i].name, ab.entries[i].last_addr, ab.entries[i].last_port);
|
||||||
|
|
||||||
|
fclose(in);
|
||||||
|
addrbook_destroy(&ab);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (argc < 4) {
|
if (argc < 4) {
|
||||||
usage();
|
usage();
|
||||||
|
@ -43,47 +51,40 @@ int main(int argc, char **argv) {
|
||||||
char *addr = argv[2];
|
char *addr = argv[2];
|
||||||
char *port = argv[3];
|
char *port = argv[3];
|
||||||
|
|
||||||
|
if (direction != 'c' && direction != 's') {
|
||||||
|
usage();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
net_t n;
|
net_t n;
|
||||||
crypt_session_t s;
|
crypt_session_t s;
|
||||||
crypt_key_t ok, rk;
|
crypt_key_t ok, rk;
|
||||||
|
|
||||||
if (crypt_key_gen(&ok) == -1) {
|
if ((result = crypt_key_gen(&ok)) == -1)
|
||||||
ret = -1;
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
|
||||||
|
|
||||||
if (direction == 'c') {
|
(direction == 'c') ?
|
||||||
if (net_client_init(&n, addr, port) == -1) {
|
(result = net_client_init(&n, addr, port))
|
||||||
ret = -1;
|
: (result = net_server_init(&n, addr, port));
|
||||||
goto cleanup;
|
if (result != 0)
|
||||||
}
|
goto cleanup;
|
||||||
|
|
||||||
int res = client_handshake(&n, &s, &ok, &rk);
|
(direction == 'c') ?
|
||||||
|
(result = client_handshake(&n, &s, &ok, &rk))
|
||||||
|
: (result = server_handshake(&n, &s, &ok, &rk));
|
||||||
|
if (result != 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
char rkph[CRYPT_PKEY_HEXLEN];
|
||||||
|
|
||||||
if (res != 0) {
|
crypt_key_export_public(&rk, rkph);
|
||||||
ret = res;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
} else if (direction == 's') {
|
|
||||||
if (net_server_init(&n, addr, port) == -1) {
|
|
||||||
ret = -1;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
int res = server_handshake(&n, &s, &ok, &rk);
|
fprintf(stderr, "A connection with %s established!\n", rkph);
|
||||||
|
|
||||||
if (res != 0) {
|
|
||||||
ret = -1;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
usage();
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, "A connection established!\n");
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
|
||||||
|
addrbook_destroy(&ab);
|
||||||
net_destroy(&n);
|
net_destroy(&n);
|
||||||
crypt_session_destroy(&s);
|
crypt_session_destroy(&s);
|
||||||
crypt_key_destroy(&ok);
|
crypt_key_destroy(&ok);
|
||||||
|
@ -92,14 +93,35 @@ cleanup:
|
||||||
// if (audio_terminate_soundsystem() == -1)
|
// if (audio_terminate_soundsystem() == -1)
|
||||||
// return -1;
|
// return -1;
|
||||||
|
|
||||||
return ret;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int handshake(const unsigned char * hello, const char * remote_hello, crypt_session_t *const s, crypt_key_t *const ok, crypt_key_t *const rk) {
|
||||||
|
unsigned char *nonce = NULL;
|
||||||
|
|
||||||
|
if (crypt_key_from_hex_public(rk, remote_hello) == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (crypt_hello_verify((unsigned char *)remote_hello, rk) == -1)
|
||||||
|
return -2;
|
||||||
|
|
||||||
|
if ((nonce = crypt_hello_get_nonce(hello, (unsigned char *)remote_hello, true)) == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (crypt_session_init(s, ok, rk, nonce, true) == -1) {
|
||||||
|
free(nonce);
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(nonce);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int client_handshake(net_t *const n, crypt_session_t *const s, crypt_key_t *const ok, crypt_key_t *const rk) {
|
int client_handshake(net_t *const n, crypt_session_t *const s, crypt_key_t *const ok, crypt_key_t *const rk) {
|
||||||
char buffer[NET_BUF_SIZE];
|
char buffer[NET_BUF_SIZE];
|
||||||
ssize_t bytes = 0;
|
ssize_t bytes = 0;
|
||||||
unsigned char *hello = NULL;
|
unsigned char *hello = NULL;
|
||||||
unsigned char *nonce = NULL;
|
|
||||||
|
|
||||||
if ((hello = crypt_hello(ok)) == NULL)
|
if ((hello = crypt_hello(ok)) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -119,38 +141,17 @@ int client_handshake(net_t *const n, crypt_session_t *const s, crypt_key_t *cons
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (crypt_key_from_hex_public(rk, buffer) == -1) {
|
int res = handshake(hello, buffer, s, ok, rk);
|
||||||
free(hello);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (crypt_hello_verify((unsigned char *)buffer, rk) == -1) {
|
|
||||||
free(hello);
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((nonce = crypt_hello_get_nonce(hello, (unsigned char *)buffer, true)) == NULL) {
|
|
||||||
free(hello);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(hello);
|
free(hello);
|
||||||
|
|
||||||
if (crypt_session_init(s, ok, rk, nonce, true) == -1) {
|
return res;
|
||||||
free(nonce);
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(nonce);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int server_handshake(net_t *const n, crypt_session_t *const s, crypt_key_t *const ok, crypt_key_t *const rk) {
|
int server_handshake(net_t *const n, crypt_session_t *const s, crypt_key_t *const ok, crypt_key_t *const rk) {
|
||||||
char buffer[NET_BUF_SIZE];
|
char buffer[NET_BUF_SIZE];
|
||||||
ssize_t bytes = 0;
|
ssize_t bytes = 0;
|
||||||
unsigned char *hello = NULL;
|
unsigned char *hello = NULL;
|
||||||
unsigned char *nonce = NULL;
|
|
||||||
|
|
||||||
if ((bytes = net_recv(n, buffer, NET_BUF_SIZE)) == -1)
|
if ((bytes = net_recv(n, buffer, NET_BUF_SIZE)) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -158,23 +159,14 @@ int server_handshake(net_t *const n, crypt_session_t *const s, crypt_key_t *cons
|
||||||
if (CRYPT_HELLO_LEN != bytes)
|
if (CRYPT_HELLO_LEN != bytes)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (crypt_key_from_hex_public(rk, buffer) == -1)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (crypt_hello_verify((unsigned char *)buffer, rk) == -1)
|
|
||||||
return -2;
|
|
||||||
|
|
||||||
if ((hello = crypt_hello(ok)) == NULL)
|
if ((hello = crypt_hello(ok)) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ((nonce = crypt_hello_get_nonce(hello, (unsigned char *)buffer, false)) == NULL) {
|
|
||||||
free(hello);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (crypt_session_init(s, ok, rk, nonce, false) == -1) {
|
int res = handshake(hello, buffer, s, ok, rk);
|
||||||
free(nonce);
|
if (res != 0) {
|
||||||
return -3;
|
free(hello);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
n->raddr = n->inaddr;
|
n->raddr = n->inaddr;
|
||||||
|
@ -186,7 +178,6 @@ int server_handshake(net_t *const n, crypt_session_t *const s, crypt_key_t *cons
|
||||||
}
|
}
|
||||||
|
|
||||||
free(hello);
|
free(hello);
|
||||||
free(nonce);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
Loading…
Reference in New Issue