This commit is contained in:
Jfreegman 2013-08-04 02:40:57 -04:00
commit 357c02ac22
12 changed files with 151 additions and 59 deletions

View File

@ -101,6 +101,7 @@ Grab the following packages:
* http://www.gnu.org/software/automake/ * http://www.gnu.org/software/automake/
* http://www.cmake.org/ * http://www.cmake.org/
* https://github.com/jedisct1/libsodium * https://github.com/jedisct1/libsodium
* http://www.hyperrealm.com/libconfig/
Uncompress and install them all. Make sure to follow the README as the instructions change, but they all follow the same pattern below: Uncompress and install them all. Make sure to follow the README as the instructions change, but they all follow the same pattern below:
@ -118,7 +119,7 @@ make
``` ```
Do not install them from macports (or any dependencies for that matter) as they get shoved in the wrong directory Do not install them from macports (or any dependencies for that matter) as they get shoved in the wrong directory
and make your life more annoying. (or the wrong version gets installed) and make your life more annoying.
Another thing you may want to install is the latest gcc, this caused me a few problems as XCode from 4.3 Another thing you may want to install is the latest gcc, this caused me a few problems as XCode from 4.3
no longer includes gcc and instead uses LLVM-GCC, a nice install guide can be found at no longer includes gcc and instead uses LLVM-GCC, a nice install guide can be found at

View File

@ -22,7 +22,7 @@ Keep everything really simple.
## The Complex Stuff: ## The Complex Stuff:
+ Tox must use UDP simply because [hole punching](http://en.wikipedia.org/wiki/UDP_hole_punching) with TCP is not as reliable. + Tox must use UDP simply because [hole punching](http://en.wikipedia.org/wiki/UDP_hole_punching) with TCP is not as reliable.
+ Every peer is represented as a [byte string](https://en.wikipedia.org/wiki/String_(computer_science)) (the public key of the peer [client ID]). + Every peer is represented as a [byte string][String] (the public key of the peer [client ID]).
+ We're using torrent-style DHT so that peers can find the IP of the other peers when they have their ID. + We're using torrent-style DHT so that peers can find the IP of the other peers when they have their ID.
+ Once the client has the IP of that peer, they start initiating a secure connection with each other. (See [Crypto](https://github.com/irungentoo/ProjectTox-Core/wiki/Crypto)) + Once the client has the IP of that peer, they start initiating a secure connection with each other. (See [Crypto](https://github.com/irungentoo/ProjectTox-Core/wiki/Crypto))
+ When both peers are securely connected, they can exchange messages, initiate a video chat, send files, etc, all using encrypted communications. + When both peers are securely connected, they can exchange messages, initiate a video chat, send files, etc, all using encrypted communications.
@ -53,3 +53,5 @@ configure for the normal user or suffer from being way too centralized.
- [Lossless UDP Protocol](https://github.com/irungentoo/ProjectTox-Core/wiki/Lossless-UDP)<br /> - [Lossless UDP Protocol](https://github.com/irungentoo/ProjectTox-Core/wiki/Lossless-UDP)<br />
- [Crypto](https://github.com/irungentoo/ProjectTox-Core/wiki/Crypto)<br /> - [Crypto](https://github.com/irungentoo/ProjectTox-Core/wiki/Crypto)<br />
- [Ideas](https://github.com/irungentoo/ProjectTox-Core/wiki/Ideas) - [Ideas](https://github.com/irungentoo/ProjectTox-Core/wiki/Ideas)
[String]: https://en.wikipedia.org/wiki/String_(computer_science)

View File

@ -17,3 +17,4 @@ set(core_sources
Messenger.c) Messenger.c)
add_library(toxcore SHARED ${core_sources}) add_library(toxcore SHARED ${core_sources})
target_link_libraries(toxcore ${SODIUM_LIBRARY})

View File

@ -1,6 +1,6 @@
/* DHT.c /* DHT.c
* *
* An implementation of the DHT as seen in docs/DHT.txt * An implementation of the DHT as seen in http://wiki.tox.im/index.php/DHT
* *
* Copyright (C) 2013 Tox project All Rights Reserved. * Copyright (C) 2013 Tox project All Rights Reserved.
* *

View File

@ -1,6 +1,6 @@
/* DHT.h /* DHT.h
* *
* An implementation of the DHT as seen in docs/DHT.txt * An implementation of the DHT as seen in http://wiki.tox.im/index.php/DHT
* *
* Copyright (C) 2013 Tox project All Rights Reserved. * Copyright (C) 2013 Tox project All Rights Reserved.
* *

View File

@ -1,6 +1,6 @@
/* Lossless_UDP.c /* Lossless_UDP.c
* *
* An implementation of the Lossless_UDP protocol as seen in docs/Lossless_UDP.txt * An implementation of the Lossless_UDP protocol as seen in http://wiki.tox.im/index.php/Lossless_UDP
* *
* Copyright (C) 2013 Tox project All Rights Reserved. * Copyright (C) 2013 Tox project All Rights Reserved.
* *
@ -467,7 +467,7 @@ uint32_t missing_packets(int connection_id, uint32_t * requested)
/* /*
* BEGIN Packet sending functions * BEGIN Packet sending functions
* One per packet type. * One per packet type.
* see docs/Lossless_UDP.txt for more information. * see http://wiki.tox.im/index.php/Lossless_UDP for more information.
*/ */
int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2) int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2)

View File

@ -1,6 +1,6 @@
/* Lossless_UDP.h /* Lossless_UDP.h
* *
* An implementation of the Lossless_UDP protocol as seen in docs/Lossless_UDP.txt * An implementation of the Lossless_UDP protocol as seen in http://wiki.tox.im/index.php/Lossless_UDP
* *
* Copyright (C) 2013 Tox project All Rights Reserved. * Copyright (C) 2013 Tox project All Rights Reserved.
* *

View File

@ -1,7 +1,7 @@
/* net_crypto.c /* net_crypto.c
* *
* Functions for the core network crypto. * Functions for the core network crypto.
* See also: docs/Crypto.txt * See also: http://wiki.tox.im/index.php/DHT
* *
* NOTE: This code has to be perfect. We don't mess around with encryption. * NOTE: This code has to be perfect. We don't mess around with encryption.
* *

View File

@ -36,11 +36,12 @@
char lines[HISTORY][STRING_LENGTH]; char lines[HISTORY][STRING_LENGTH];
char line[STRING_LENGTH]; char line[STRING_LENGTH];
char *help = "[i] commands: /f ID (to add friend), /m friendnumber message (to send message), /s status (to change status)\n" char *help = "[i] commands:\n/f ID (to add friend)\n/m friendnumber message "
"[i] /l list (list friends), /h for help, /i for info, /n nick (to change nickname), /q (to quit)"; "(to send message)\n/s status (to change status)\n[i] /l list (l"
"ist friends)\n/h for help\n/i for info\n/n nick (to change nick"
"name)\n/q (to quit)";
int x, y; int x, y;
uint8_t pending_requests[256][CLIENT_ID_SIZE]; uint8_t pending_requests[256][CLIENT_ID_SIZE];
uint8_t num_requests = 0; uint8_t num_requests = 0;
@ -82,18 +83,23 @@ void new_lines(char *line)
void print_friendlist() void print_friendlist()
{ {
char name[MAX_NAME_LENGTH]; char name[MAX_NAME_LENGTH];
int i = 0;
new_lines("[i] Friend List:"); new_lines("[i] Friend List:");
uint32_t i; while(getname(i, (uint8_t *)name) != -1) {
for (i = 0; i <= num_requests; i++) { /* account for the longest name and the longest "base" string */
char fstring[128]; char fstring[MAX_NAME_LENGTH + strlen("[i] Friend: NULL\n\tid: ")];
getname(i, (uint8_t*)name);
if (strlen(name) <= 0) { if (strlen(name) <= 0) {
sprintf(fstring, "[i] Friend: NULL\n\tid: %i", i); sprintf(fstring, "[i] Friend: No Friend!\n\tid: %i", i);
} else { } else {
sprintf(fstring, "[i] Friend: %s\n\tid: %i", (uint8_t*)name, i); sprintf(fstring, "[i] Friend: %s\n\tid: %i", (uint8_t*)name, i);
} }
i++;
new_lines(fstring); new_lines(fstring);
} }
if(i == 0)
new_lines("\tno friends! D:");
} }
char *format_message(char *message, int friendnum) char *format_message(char *message, int friendnum)
@ -122,7 +128,7 @@ char *format_message(char *message, int friendnum)
return msg; return msg;
} }
void line_eval(char lines[HISTORY][STRING_LENGTH], char *line) void line_eval(char *line)
{ {
if (line[0] == '/') { if (line[0] == '/') {
char inpt_command = line[1]; char inpt_command = line[1];
@ -236,8 +242,7 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
do_refresh(); do_refresh();
} }
else if (inpt_command == 'h') { //help else if (inpt_command == 'h') { //help
new_lines("[i] commands: /f ID (to add friend), /m friendnumber message (to send message), /s status (to change status)"); new_lines(help);
new_lines("[i] /l list (list friends), /h for help, /i for info, /n nick (to change nickname), /q (to quit)");
} }
else if (inpt_command == 'i') { //info else if (inpt_command == 'i') { //info
char idstring[200]; char idstring[200];
@ -353,10 +358,10 @@ void print_statuschange(int friendnumber, uint8_t *string, uint16_t length)
new_lines(msg); new_lines(msg);
} }
void load_key() void load_key(char *path)
{ {
FILE *data_file = NULL; FILE *data_file = fopen(path, "r");
data_file = fopen("data","r");
if (data_file) { if (data_file) {
//load keys //load keys
fseek(data_file, 0, SEEK_END); fseek(data_file, 0, SEEK_END);
@ -368,51 +373,81 @@ void load_key()
exit(1); exit(1);
} }
Messenger_load(data, size); Messenger_load(data, size);
} else {
} else {
//else save new keys //else save new keys
int size = Messenger_size(); int size = Messenger_size();
uint8_t data[size]; uint8_t data[size];
Messenger_save(data); Messenger_save(data);
data_file = fopen("data","w"); data_file = fopen(path, "w");
if(!data_file) {
perror("[!] load_key");
exit(1);
}
if (fwrite(data, sizeof(uint8_t), size, data_file) != size){ if (fwrite(data, sizeof(uint8_t), size, data_file) != size){
printf("[i] could not write data file\n[i] exiting\n"); puts("[i] could not write data file! exiting...");
exit(1); exit(1);
} }
} }
fclose(data_file); fclose(data_file);
} }
void print_help(void)
{
printf("nTox %.1f - Command-line tox-core client\n", 0.1);
puts("Options:");
puts("\t-h\t-\tPrint this help and exit.");
puts("\t-f\t-\tSpecify a keyfile to read (or write to) from.");
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int on = 0;
int c = 0;
int i = 0;
char *filename = "data";
char idstring[200] = {0};
if (argc < 4) { if (argc < 4) {
printf("[!] Usage: %s [IP] [port] [public_key] <nokey>\n", argv[0]); printf("[!] Usage: %s [IP] [port] [public_key] <keyfile>\n", argv[0]);
exit(0); exit(0);
} }
int c;
int on = 0; for(i = 0; i < argc; i++) {
initMessenger(); if(argv[i][0] == '-') {
//if keyfiles exist if(argv[i][1] == 'h') {
if(argc > 4){ print_help();
if(strncmp(argv[4], "nokey", 6) < 0){ exit(0);
//load_key(); } else if(argv[i][1] == 'f') {
if(argv[i + 1] != NULL)
filename = argv[i + 1];
else {
fputs("[!] you passed '-f' without giving an argument!\n", stderr);
}
}
} }
} else {
load_key();
} }
initMessenger();
load_key(filename);
m_callback_friendrequest(print_request); m_callback_friendrequest(print_request);
m_callback_friendmessage(print_message); m_callback_friendmessage(print_message);
m_callback_namechange(print_nickchange); m_callback_namechange(print_nickchange);
m_callback_userstatus(print_statuschange); m_callback_userstatus(print_statuschange);
char idstring[200];
get_id(idstring);
initscr(); initscr();
noecho(); noecho();
raw(); raw();
getmaxyx(stdscr, y, x); getmaxyx(stdscr, y, x);
new_lines("/h for list of commands");
get_id(idstring);
new_lines(idstring); new_lines(idstring);
new_lines(help);
strcpy(line, ""); strcpy(line, "");
IP_Port bootstrap_ip_port; IP_Port bootstrap_ip_port;
bootstrap_ip_port.port = htons(atoi(argv[2])); bootstrap_ip_port.port = htons(atoi(argv[2]));
int resolved_address = resolve_addr(argv[1]); int resolved_address = resolve_addr(argv[1]);
@ -439,7 +474,7 @@ int main(int argc, char *argv[])
getmaxyx(stdscr, y, x); getmaxyx(stdscr, y, x);
if (c == '\n') { if (c == '\n') {
line_eval(lines, line); line_eval(line);
strcpy(line, ""); strcpy(line, "");
} else if (c == 8 || c == 127) { } else if (c == 8 || c == 127) {
line[strlen(line)-1] = '\0'; line[strlen(line)-1] = '\0';

View File

@ -37,12 +37,13 @@
#include <netdb.h> #include <netdb.h>
#include "../core/Messenger.h" #include "../core/Messenger.h"
#include "../core/network.h" #include "../core/network.h"
#define STRING_LENGTH 256 #define STRING_LENGTH 256
#define HISTORY 50 #define HISTORY 50
#define PUB_KEY_BYTES 32 #define PUB_KEY_BYTES 32
void new_lines(char *line); void new_lines(char *line);
void line_eval(char lines[HISTORY][STRING_LENGTH], char *line); void line_eval(char *line);
void wrap(char output[STRING_LENGTH], char input[STRING_LENGTH], int line_width) ; void wrap(char output[STRING_LENGTH], char input[STRING_LENGTH], int line_width) ;
int count_lines(char *string) ; int count_lines(char *string) ;
char *appender(char *str, const char c); char *appender(char *str, const char c);

View File

@ -7,6 +7,7 @@
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
#include <ctype.h> #include <ctype.h>
#include <time.h>
#include "../../core/Messenger.h" #include "../../core/Messenger.h"
#include "../../core/network.h" #include "../../core/network.h"
@ -26,11 +27,15 @@ typedef struct {
extern void fix_name(uint8_t* name); extern void fix_name(uint8_t* name);
static void chat_onMessage(ToxWindow* self, int num, uint8_t* msg, uint16_t len) { static void chat_onMessage(ToxWindow* self, int num, uint8_t* msg, uint16_t len) {
ChatContext* ctx = (ChatContext*) self->x; ChatContext* ctx = (ChatContext*) self->x;
uint8_t nick[MAX_NAME_LENGTH] = {0}; uint8_t nick[MAX_NAME_LENGTH] = {0};
time_t now;
time(&now);
struct tm * timeinfo;
timeinfo = localtime(&now);
if(ctx->friendnum != num) if(ctx->friendnum != num)
return; return;
@ -42,10 +47,11 @@ static void chat_onMessage(ToxWindow* self, int num, uint8_t* msg, uint16_t len)
fix_name(msg); fix_name(msg);
fix_name(nick); fix_name(nick);
wattron(ctx->history, COLOR_PAIR(2));
wprintw(ctx->history, "%02d:%02d:%02d ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
wattron(ctx->history, COLOR_PAIR(4)); wattron(ctx->history, COLOR_PAIR(4));
wprintw(ctx->history, "%s: ", nick); wprintw(ctx->history, "%s: ", nick);
wattroff(ctx->history, COLOR_PAIR(4)); wattroff(ctx->history, COLOR_PAIR(4));
wprintw(ctx->history, "%s\n", msg); wprintw(ctx->history, "%s\n", msg);
self->blink = true; self->blink = true;
@ -71,9 +77,26 @@ static void chat_onStatusChange(ToxWindow* self, int num, uint8_t* status, uint1
} }
/* check that the string has one non-space character */
int string_is_empty(char *string)
{
int rc = 0;
char *copy = strdup(string);
rc = ((strtok(copy, " ") == NULL) ? 1:0);
free(copy);
return rc;
}
static void chat_onKey(ToxWindow* self, int key) { static void chat_onKey(ToxWindow* self, int key) {
ChatContext* ctx = (ChatContext*) self->x; ChatContext* ctx = (ChatContext*) self->x;
time_t now;
time(&now);
struct tm * timeinfo;
timeinfo = localtime(&now);
if(isprint(key)) { if(isprint(key)) {
if(ctx->pos != sizeof(ctx->line)-1) { if(ctx->pos != sizeof(ctx->line)-1) {
@ -81,28 +104,34 @@ static void chat_onKey(ToxWindow* self, int key) {
ctx->line[ctx->pos] = '\0'; ctx->line[ctx->pos] = '\0';
} }
} }
else if(key == '\n') { else if(key == '\n') {
wattron(ctx->history, COLOR_PAIR(1)); if(!string_is_empty(ctx->line)) {
wprintw(ctx->history, "you: ", ctx->line); /* make sure the string has at least non-space character */
wattroff(ctx->history, COLOR_PAIR(1)); wattron(ctx->history, COLOR_PAIR(2));
wprintw(ctx->history, "%02d:%02d:%02d ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
wattron(ctx->history, COLOR_PAIR(1));
wprintw(ctx->history, "you: ", ctx->line);
wattroff(ctx->history, COLOR_PAIR(1));
wprintw(ctx->history, "%s\n", ctx->line);
wprintw(ctx->history, "%s\n", ctx->line); if(m_sendmessage(ctx->friendnum, (uint8_t*) ctx->line, strlen(ctx->line)+1) < 0) {
wattron(ctx->history, COLOR_PAIR(3));
wprintw(ctx->history, " * Failed to send message.\n");
wattroff(ctx->history, COLOR_PAIR(3));
}
if(m_sendmessage(ctx->friendnum, (uint8_t*) ctx->line, strlen(ctx->line)+1) < 0) { ctx->line[0] = '\0';
wattron(ctx->history, COLOR_PAIR(3)); ctx->pos = 0;
wprintw(ctx->history, " * Failed to send message.\n");
wattroff(ctx->history, COLOR_PAIR(3));
} }
ctx->line[0] = '\0';
ctx->pos = 0;
} }
else if(key == 0x107 || key == 0x8 || key == 0x7f) { else if(key == 0x107 || key == 0x8 || key == 0x7f) {
if(ctx->pos != 0) { if(ctx->pos != 0) {
ctx->line[--ctx->pos] = '\0'; ctx->line[--ctx->pos] = '\0';
} }
} }
} }
static void chat_onDraw(ToxWindow* self) { static void chat_onDraw(ToxWindow* self) {
@ -150,7 +179,7 @@ ToxWindow new_chat(int friendnum) {
uint8_t nick[MAX_NAME_LENGTH] = {0}; uint8_t nick[MAX_NAME_LENGTH] = {0};
getname(friendnum, (uint8_t*) &nick); getname(friendnum, (uint8_t*) &nick);
fix_name(nick); fix_name(nick);
snprintf(ret.title, sizeof(ret.title), "[%s (%d)]", nick, friendnum); snprintf(ret.title, sizeof(ret.title), "[%s (%d)]", nick, friendnum);
ChatContext* x = calloc(1, sizeof(ChatContext)); ChatContext* x = calloc(1, sizeof(ChatContext));

View File

@ -170,12 +170,12 @@ static void do_tox() {
doMessenger(); doMessenger();
} }
static void load_data() { static void load_data(char *path) {
FILE* fd; FILE* fd;
size_t len; size_t len;
uint8_t* buf; uint8_t* buf;
if((fd = fopen("data", "r")) != NULL) { if((fd = fopen(path, "r")) != NULL) {
fseek(fd, 0, SEEK_END); fseek(fd, 0, SEEK_END);
len = ftell(fd); len = ftell(fd);
fseek(fd, 0, SEEK_SET); fseek(fd, 0, SEEK_SET);
@ -213,7 +213,7 @@ static void load_data() {
Messenger_save(buf); Messenger_save(buf);
fd = fopen("data", "w"); fd = fopen(path, "w");
if(fd == NULL) { if(fd == NULL) {
fprintf(stderr, "fopen() failed.\n"); fprintf(stderr, "fopen() failed.\n");
@ -282,13 +282,36 @@ void prepare_window(WINDOW* w) {
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
int ch; int ch;
int i = 0;
int f_flag = 0;
char *filename = "data";
ToxWindow* a; ToxWindow* a;
for(i = 0; i < argc; i++) {
if(argv[i][0] == '-') {
if(argv[i][1] == 'f') {
if(argv[i + 1] != NULL)
filename = argv[i + 1];
else {
f_flag = -1;
}
}
}
}
init_term(); init_term();
init_tox(); init_tox();
load_data(); load_data(filename);
init_windows(); init_windows();
if(f_flag == -1) {
attron(COLOR_PAIR(3) | A_BOLD);
wprintw(prompt->window, "You passed '-f' without giving an argument!\n"
"defaulting to 'data' for a keyfile...\n");
attroff(COLOR_PAIR(3) | A_BOLD);
}
while(true) { while(true) {
// Update tox. // Update tox.
do_tox(); do_tox();