1
0
mirror of https://github.com/Tha14/toxic.git synced 2025-06-26 22:56:46 +02:00

Compare commits

...

12 Commits

Author SHA1 Message Date
310cf464d0 Fix bug causing messages containing newline byte to disappear
The wcswidth() function was silently failing when trying to convert
messages containing a newline to a widechar buffer which resulted
in the message showing up as an empty line. we now fall back
to using strlen to get the width of the string, which might still
cause minor display bugs when the message contains unicode, but is
still better than losing messages entirely.
2022-03-02 15:58:21 -05:00
0c11b3121a Update static musl build script
Bump toxcore to v0.2.16 and add new msgpack dependency
2022-02-20 13:12:23 -05:00
1bdf0041bc Bump toxic and curl versions in static build script 2022-02-12 21:17:19 -05:00
6a203fd7bf Make sure we compare wchars to wchars instead of bytes 2022-02-03 13:01:08 -05:00
93b3bbd5f6 chore: Use latest instead of versioned toktok-stack image. 2022-01-30 19:32:00 +00:00
e122c5dbca Use widechars to display strings in the UI
This fixes a bug where printing a bunch of UTF8 chars with glyphs
that have a size > 1 would make the entire chat window disappear.
It also fixes an issue where said UTF8 chars would be truncated
and generally not display correctly.
2022-01-27 15:45:56 -05:00
f6f41a510b Add some simple impersonation detection on friend requests
This will alert the user when the first six bytes of a new
contact's public key is the same as any other contact in
their list. These 6 bytes are used elsewhere in toxic for
unique identification.

Also did a small refactor regarding the KEY_IDENT_BYTES
define
2022-01-23 11:32:57 -05:00
05dbc626e2 Make sure we check for duplicate paths in pending file transfers list
This fixes a bug where if you receive multiple file transfer
requests simultaneously and they have the same path the files
will overwrite each other
2022-01-17 10:53:34 -05:00
ceb175e3f1 chore: Add check that the static build script works.
Otherwise it'll break again in the future and we won't know.
2022-01-13 01:37:24 +00:00
4bd1d9bfee Update libbrotli pc file sed
libbrotli has updated its .pc files since the last sed was written, so
it didn't work anymore, resulting in Toxic build failing. However, the
way they have updated it, it's still broken, so a different sed is
needed.
2022-01-05 15:55:30 -05:00
55944aa5a9 Remove broken Docker check
The Docker detection method doesn't work on cgroup v2 systems, so the
script just keeps erroring out.

There doesn't seem to be a simple way to detect that we are running
inside a Docker container, so it makes sense to drop that check
altogether.
2022-01-05 15:52:57 -05:00
b71c6a3792 Improve static build script documentation 2022-01-05 15:51:52 -05:00
14 changed files with 208 additions and 89 deletions

View File

@ -1,7 +1,7 @@
---
cirrus-ci_task:
bazel-opt_task:
container:
image: toxchat/toktok-stack:0.0.31-third_party
image: toxchat/toktok-stack:latest-release
cpu: 2
memory: 2G
configure_script:
@ -9,5 +9,4 @@ cirrus-ci_task:
test_all_script:
- cd /src/workspace && bazel test -k
--remote_http_cache=http://$CIRRUS_HTTP_CACHE_HOST
--config=release
//toxic/...

View File

@ -12,7 +12,8 @@ branches:
required_status_checks:
contexts:
- build
- cirrus-ci
- build-static
- bazel-opt
- Codacy Static Code Analysis
- code-review/reviewable
- infer

View File

@ -18,6 +18,7 @@ jobs:
libalut-dev
libconfig-dev
libcurl4-gnutls-dev
libmsgpack-dev
libnotify-dev
libopenal-dev
libopus-dev
@ -37,6 +38,22 @@ jobs:
- name: Build toxic
run: make -j4
build-static:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Build minimal static toxic binary
run: docker run --rm
-v /tmp/artifact:/artifact
-v $PWD:/toxic
amd64/alpine:latest
sh -c 'yes | /toxic/script/build-minimal-static-toxic.sh'
- name: Display binary checksum
run: |
tar Jxf /tmp/artifact/toxic-minimal-static-musl_linux_x86-64.tar.xz
sha256sum toxic-minimal-static-musl_linux_x86-64/toxic
infer:
runs-on: ubuntu-latest
container: toxchat/infer
@ -56,6 +73,7 @@ jobs:
libalut-dev
libconfig-dev
libcurl4-gnutls-dev
libmsgpack-dev
libncurses-dev
libnotify-dev
libopenal-dev
@ -87,6 +105,7 @@ jobs:
libnotify
libpng
libqrencode
msgpack
ncurses
openal
python3

View File

@ -1,6 +1,8 @@
load("@rules_cc//cc:defs.bzl", "cc_binary")
load("//tools/project:build_defs.bzl", "project")
package(features = ["layering_check"])
project()
cc_binary(

View File

@ -2,7 +2,7 @@
# MIT License
#
# Copyright (c) 2021 Maxim Biro <nurupo.contributions@gmail.com>
# Copyright (c) 2021-2022 Maxim Biro <nurupo.contributions@gmail.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@ -36,8 +36,19 @@
#
# that would use Toxic code from /home/jfreegman/git/toxic and place the build
# artifact at /tmp/artifact.
# You can change between amd64/alpine:latest and i386/alpine:latest, for 64-bit
# and 32-bit builds.
#
# You can change between:
# amd64/alpine:latest,
# i386/alpine:latest,
# arm64v8/alpine:latest,
# arm32v7/alpine:latest,
# arm32v6/alpine:latest,
# ppc64le/alpine:latest,
# s390x/alpine:latest,
# etc.
# as long as your system can run foreign architecture binaries, e.g. via qemu
# static bins and binfmt (install qemu-user-static package on Debian/Ubuntu).
#
#
# To debug, run:
#
@ -53,13 +64,6 @@ set -eu
ARTIFACT_DIR="/artifact"
TOXIC_SRC_DIR="/toxic"
# Make sure we run in the expected environment
if ! grep -q 'docker' /proc/1/cgroup
then
echo "Error: This script should be run inside a disposable Docker container as it might modify system files in ways that would break a real system."
exit 1
fi
if [ ! -f /etc/os-release ] || ! grep -qi 'Alpine Linux' /etc/os-release
then
echo "Error: This script expects to be run on Alpine Linux."
@ -110,6 +114,7 @@ apk add \
libsodium-dev \
libsodium-static \
linux-headers \
msgpack-c-dev \
ncurses-dev \
ncurses-static \
ncurses-terminfo \
@ -132,10 +137,10 @@ mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"
# The git hash of the c-toxcore version we're using
TOXCORE_VERSION="v0.2.13"
TOXCORE_VERSION="v0.2.16"
# The sha256sum of the c-toxcore tarball for TOXCORE_VERSION
TOXCORE_HASH="67114fa57504c58b695f5dce8ef85124d555f2c3c353d0d2615e6d4845114ab8"
TOXCORE_HASH="653aa42654b607f0940cecfac873e9ce55605119a90d1dc454d1090ff6ca29c0"
TOXCORE_FILENAME="c-toxcore-$TOXCORE_VERSION.tar.gz"
@ -164,8 +169,8 @@ cmake --build _build --target install
# location with SSL_CERT_FILE env variable.
cd "$BUILD_DIR"
CURL_VERSION="7.80.0"
CURL_HASH="dab997c9b08cb4a636a03f2f7f985eaba33279c1c52692430018fae4a4878dc7"
CURL_VERSION="7.81.0"
CURL_HASH="ac8e1087711084548d788ef18b9b732c8de887457b81f616fc681d1044b32f98"
CURL_FILENAME="curl-$CURL_VERSION.tar.gz"
wget --timeout=10 -O "$CURL_FILENAME" "https://curl.haxx.se/download/$CURL_FILENAME"
@ -186,7 +191,8 @@ cd curl*
--with-openssl
make
make install
sed -i 's|-lbrotlidec |-lbrotlidec-static -lbrotlicommon-static |g' $BUILD_DIR/prefix-curl/lib/pkgconfig/libcurl.pc
sed -i 's|-lbrotlidec |-lbrotlidec -lbrotlicommon |g' $BUILD_DIR/prefix-curl/lib/pkgconfig/libcurl.pc
# Build Toxic
cd "$BUILD_DIR"
@ -301,4 +307,3 @@ mv "$PREPARE_ARTIFACT_DIR" "$PREPARE_ARTIFACT_DIR/../$ARTIFACT_NAME"
tar -cJf "$ARTIFACT_NAME.tar.xz" "$ARTIFACT_NAME"
mv "$ARTIFACT_NAME.tar.xz" "$ARTIFACT_DIR"
chmod 777 -R "$ARTIFACT_DIR"

View File

@ -676,8 +676,10 @@ static void chat_onFileRecv(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_
FILE *filecheck = NULL;
int count = 1;
while ((filecheck = fopen(file_path, "r"))) {
fclose(filecheck);
while ((filecheck = fopen(file_path, "r")) || file_transfer_recv_path_exists(file_path)) {
if (filecheck) {
fclose(filecheck);
}
file_path[path_len] = '\0';
char d[5];
@ -1383,7 +1385,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
self->x = x2;
/* Truncate note if it doesn't fit in statusbar */
size_t maxlen = x2 - getcurx(statusbar->topline) - (KEY_IDENT_DIGITS * 2) - 6;
size_t maxlen = x2 - getcurx(statusbar->topline) - KEY_IDENT_BYTES - 6;
pthread_mutex_lock(&Winthread.lock);
size_t statusmsg_len = statusbar->statusmsg_len;
@ -1414,10 +1416,10 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
int s_x;
getyx(statusbar->topline, s_y, s_x);
mvwhline(statusbar->topline, s_y, s_x, ' ', x2 - s_x - (KEY_IDENT_DIGITS * 2) - 3);
mvwhline(statusbar->topline, s_y, s_x, ' ', x2 - s_x - KEY_IDENT_BYTES - 3);
wattroff(statusbar->topline, COLOR_PAIR(BAR_TEXT));
wmove(statusbar->topline, 0, x2 - (KEY_IDENT_DIGITS * 2) - 3);
wmove(statusbar->topline, 0, x2 - KEY_IDENT_BYTES - 3);
wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wprintw(statusbar->topline, "{");
@ -1425,7 +1427,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
wattron(statusbar->topline, COLOR_PAIR(BAR_TEXT));
for (size_t i = 0; i < KEY_IDENT_DIGITS; ++i) {
for (size_t i = 0; i < KEY_IDENT_BYTES / 2; ++i) {
wprintw(statusbar->topline, "%02X", Friends.list[self->num].pub_key[i] & 0xff);
}

View File

@ -45,9 +45,8 @@ extern FriendsList Friends;
void init_progress_bar(char *progline)
{
strcpy(progline, "0% [");
int i;
for (i = 0; i < NUM_PROG_MARKS; ++i) {
for (size_t i = 0; i < NUM_PROG_MARKS; ++i) {
strcat(progline, "-");
}
@ -397,3 +396,26 @@ void kill_all_file_transfers(Tox *m)
kill_all_file_transfers_friend(m, Friends.list[i].num);
}
}
bool file_transfer_recv_path_exists(const char *path)
{
for (size_t friendnumber = 0; friendnumber < Friends.max_idx; ++friendnumber) {
if (!Friends.list[friendnumber].active) {
continue;
}
for (size_t i = 0; i < MAX_FILES; ++i) {
FileTransfer *ft = &Friends.list[friendnumber].file_receiver[i];
if (ft->state == FILE_TRANSFER_INACTIVE) {
continue;
}
if (strcmp(path, ft->file_path) == 0) {
return true;
}
}
}
return false;
}

View File

@ -145,4 +145,7 @@ void kill_all_file_transfers_friend(Tox *m, uint32_t friendnumber);
void kill_all_file_transfers(Tox *m);
/* Return true if any pending or active file receiver has the path `path`. */
bool file_transfer_recv_path_exists(const char *path);
#endif /* FILE_TRANSFERS_H */

View File

@ -20,6 +20,10 @@
*
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE /* needed for wcswidth() */
#endif
#include <stdarg.h>
#include <stdbool.h>
#include <stdlib.h>
@ -137,13 +141,13 @@ static struct line_info *line_info_ret_queue(struct history *hst)
* Return 0 if string does not contain a newline byte.
* Return -1 if printing was aborted.
*/
static int print_n_chars(WINDOW *win, const char *s, size_t n, int max_y)
static int print_n_chars(WINDOW *win, const wchar_t *s, size_t n, int max_y)
{
bool newline = false;
char ch;
wchar_t ch;
for (size_t i = 0; i < n && (ch = s[i]); ++i) {
if (ch == '\n') {
if (ch == L'\n') {
newline = true;
int x;
@ -159,7 +163,17 @@ static int print_n_chars(WINDOW *win, const char *s, size_t n, int max_y)
}
if (win) {
wprintw(win, "%c", ch);
#ifdef HAVE_WIDECHAR
waddnwstr(win, &ch, 1);
#else
char b;
if (wcstombs(&b, &ch, sizeof(char)) != 1) {
continue;
}
wprintw(win, "%c", b);
#endif // HAVE_WIDECHAR
}
}
@ -169,10 +183,10 @@ static int print_n_chars(WINDOW *win, const char *s, size_t n, int max_y)
/* Returns the index of the last space character in `s` found before `limit`.
* Returns -1 if no space is found.
*/
static int rspace_index(const char *s, int limit)
static int rspace_index(const wchar_t *s, int limit)
{
for (int i = limit; i >= 0; --i) {
if (s[i] == ' ') {
if (s[i] == L' ') {
return i;
}
}
@ -183,12 +197,12 @@ static int rspace_index(const char *s, int limit)
/* Returns the first index in `s` containing a newline byte found before `limit`.
* Returns -1 if no newline is found.
*/
static int newline_index(const char *s, int limit)
static int newline_index(const wchar_t *s, int limit)
{
char ch;
wchar_t ch;
for (int i = 0; i < limit && (ch = s[i]); ++i) {
if (ch == '\n') {
if (ch == L'\n') {
return i;
}
}
@ -197,13 +211,13 @@ static int newline_index(const char *s, int limit)
}
/* Returns the number of newline bytes in `s` */
static unsigned int newline_count(const char *s)
static unsigned int newline_count(const wchar_t *s)
{
char ch;
wchar_t ch;
unsigned int count = 0;
for (size_t i = 0; (ch = s[i]); ++i) {
if (ch == '\n') {
if (ch == L'\n') {
++count;
}
}
@ -226,10 +240,10 @@ static int print_wrap(WINDOW *win, struct line_info *line, int max_x, int max_y)
int y;
UNUSED_VAR(y);
const char *msg = line->msg;
uint16_t length = line->msg_len;
const wchar_t *msg = line->msg;
uint16_t length = line->msg_width;
uint16_t lines = 0;
const int x_start = line->len - line->msg_len - 1; // manually keep track of x position because ncurses sucks
const int x_start = line->len - line->msg_width - 1; // manually keep track of x position because ncurses sucks
int x_limit = max_x - x_start;
if (x_limit <= 1) {
@ -246,7 +260,7 @@ static int print_wrap(WINDOW *win, struct line_info *line, int max_x, int max_y)
}
if (length < x_limit) {
int p_ret = print_n_chars(win, msg, length, max_y);
const int p_ret = print_n_chars(win, msg, length, max_y);
if (p_ret == 1) {
lines += newline_count(msg);
@ -258,7 +272,7 @@ static int print_wrap(WINDOW *win, struct line_info *line, int max_x, int max_y)
break;
}
int newline_idx = newline_index(msg, x_limit - 1);
const int newline_idx = newline_index(msg, x_limit - 1);
if (newline_idx >= 0) {
if (print_n_chars(win, msg, newline_idx + 1, max_y) == -1) {
@ -272,7 +286,7 @@ static int print_wrap(WINDOW *win, struct line_info *line, int max_x, int max_y)
continue;
}
int space_idx = rspace_index(msg, x_limit - 1);
const int space_idx = rspace_index(msg, x_limit - 1);
if (space_idx >= 1) {
if (print_n_chars(win, msg, space_idx, max_y) == -1) {
@ -321,6 +335,37 @@ static int print_wrap(WINDOW *win, struct line_info *line, int max_x, int max_y)
return 0;
}
/* Converts `msg` into a widechar string and puts the result in `buf`.
*
* Returns the widechar width of the string.
*/
static uint16_t line_info_add_msg(wchar_t *buf, size_t buf_size, const char *msg)
{
if (msg == NULL || msg[0] == '\0') {
return 0;
}
const wint_t wc_msg_len = mbs_to_wcs_buf(buf, msg, buf_size);
if (wc_msg_len > 0 && wc_msg_len < buf_size) {
buf[wc_msg_len] = L'\0';
int width = wcswidth(buf, wc_msg_len);
if (width == -1) { // the best we can do on failure is to fall back to strlen
width = strlen(msg);
}
return (uint16_t)width;
} else {
fprintf(stderr, "Failed to convert string '%s' to widechar\n", msg);
const wchar_t *err = L"Failed to parse message";
uint16_t width = (uint16_t)wcslen(err);
wmemcpy(buf, err, width);
buf[width] = L'\0';
return width;
}
}
static void line_info_init_line(ToxWindow *self, struct line_info *line)
{
int y2;
@ -409,13 +454,8 @@ int line_info_add(ToxWindow *self, bool show_timestamp, const char *name1, const
break;
}
uint16_t msg_len = 0;
if (frmt_msg[0]) {
snprintf(new_line->msg, sizeof(new_line->msg), "%s", frmt_msg);
msg_len = strlen(new_line->msg);
len += msg_len;
}
const uint16_t msg_width = line_info_add_msg(new_line->msg, sizeof(new_line->msg), frmt_msg);
len += msg_width;
if (show_timestamp) {
get_time_str(new_line->timestr, sizeof(new_line->timestr));
@ -434,7 +474,7 @@ int line_info_add(ToxWindow *self, bool show_timestamp, const char *name1, const
new_line->id = (hst->line_end->id + 1 + hst->queue_size) % INT_MAX;
new_line->len = len;
new_line->msg_len = msg_len;
new_line->msg_width = msg_width;
new_line->type = type;
new_line->bold = bold;
new_line->colour = colour;
@ -518,9 +558,8 @@ void line_info_print(ToxWindow *self)
const int max_y = y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT;
const int max_x = self->show_peerlist ? x2 - 1 - SIDEBAR_WIDTH : x2;
uint16_t numlines = line->format_lines;
int print_ret = 0;
while (line && numlines++ <= max_y && print_ret == 0) {
while (line && numlines++ <= max_y) {
int y;
int x;
getyx(win, y, x);
@ -557,22 +596,22 @@ void line_info_print(ToxWindow *self)
wprintw(win, "%s %s: ", user_settings->line_normal, line->name1);
wattroff(win, COLOR_PAIR(nameclr));
if (line->msg[0] == 0) {
if (line->msg[0] == L'\0') {
waddch(win, '\n');
break;
}
if (line->msg[0] == '>') {
if (line->msg[0] == L'>') {
wattron(win, COLOR_PAIR(GREEN));
} else if (line->msg[0] == '<') {
} else if (line->msg[0] == L'<') {
wattron(win, COLOR_PAIR(RED));
}
print_ret = print_wrap(win, line, max_x, max_y);
print_wrap(win, line, max_x, max_y);
if (line->msg[0] == '>') {
if (line->msg[0] == L'>') {
wattroff(win, COLOR_PAIR(GREEN));
} else if (line->msg[0] == '<') {
} else if (line->msg[0] == L'<') {
wattroff(win, COLOR_PAIR(RED));
}
@ -592,7 +631,7 @@ void line_info_print(ToxWindow *self)
wattron(win, COLOR_PAIR(YELLOW));
wprintw(win, "%s %s ", user_settings->line_normal, line->name1);
print_ret = print_wrap(win, line, max_x, max_y);
print_wrap(win, line, max_x, max_y);
wattroff(win, COLOR_PAIR(YELLOW));
waddch(win, '\n');
@ -613,7 +652,7 @@ void line_info_print(ToxWindow *self)
wattron(win, COLOR_PAIR(line->colour));
}
print_ret = print_wrap(win, line, max_x, max_y);
print_wrap(win, line, max_x, max_y);
waddch(win, '\n');
if (line->bold) {
@ -631,8 +670,8 @@ void line_info_print(ToxWindow *self)
wprintw(win, "$ ");
wattroff(win, COLOR_PAIR(GREEN));
if (line->msg[0]) {
print_ret = print_wrap(win, line, max_x, max_y);
if (line->msg[0] != L'\0') {
print_wrap(win, line, max_x, max_y);
}
waddch(win, '\n');
@ -650,7 +689,7 @@ void line_info_print(ToxWindow *self)
wprintw(win, "%s ", line->name1);
wattroff(win, A_BOLD);
print_ret = print_wrap(win, line, max_x, max_y);
print_wrap(win, line, max_x, max_y);
waddch(win, '\n');
wattroff(win, COLOR_PAIR(line->colour));
@ -669,7 +708,7 @@ void line_info_print(ToxWindow *self)
wprintw(win, "%s ", line->name1);
wattroff(win, A_BOLD);
print_ret = print_wrap(win, line, max_x, max_y);
print_wrap(win, line, max_x, max_y);
waddch(win, '\n');
wattroff(win, COLOR_PAIR(line->colour));
@ -687,7 +726,7 @@ void line_info_print(ToxWindow *self)
wprintw(win, "%s", line->name1);
wattroff(win, A_BOLD);
print_ret = print_wrap(win, line, max_x, max_y);
print_wrap(win, line, max_x, max_y);
wattron(win, A_BOLD);
wprintw(win, "%s\n", line->name2);
@ -749,10 +788,9 @@ void line_info_set(ToxWindow *self, uint32_t id, char *msg)
while (line) {
if (line->id == id) {
size_t new_len = strlen(msg);
line->len = line->len - line->msg_len + new_len;
line->msg_len = new_len;
snprintf(line->msg, sizeof(line->msg), "%s", msg);
const uint16_t new_width = line_info_add_msg(line->msg, sizeof(line->msg), msg);
line->len = line->len - line->msg_width + new_width;
line->msg_width = new_width;
return;
}

View File

@ -46,11 +46,11 @@ typedef enum LINE_TYPE {
} LINE_TYPE;
struct line_info {
char timestr[TIME_STR_SIZE];
char name1[TOXIC_MAX_NAME_LENGTH + 1];
char name2[TOXIC_MAX_NAME_LENGTH + 1];
char msg[MAX_LINE_INFO_MSG_SIZE];
time_t timestamp;
char timestr[TIME_STR_SIZE];
char name1[TOXIC_MAX_NAME_LENGTH + 1];
char name2[TOXIC_MAX_NAME_LENGTH + 1];
wchar_t msg[MAX_LINE_INFO_MSG_SIZE];
time_t timestamp;
uint8_t type;
uint8_t bold;
uint8_t colour;
@ -58,7 +58,7 @@ struct line_info {
bool read_flag; /* true if a message has been flagged as read */
uint32_t id;
uint16_t len; /* combined length of entire line */
uint16_t msg_len; /* length of the message */
uint16_t msg_width; /* width of the message */
uint16_t format_lines; /* number of lines the combined string takes up (dynamically set) */
struct line_info *prev;

View File

@ -62,21 +62,21 @@ static int get_log_path(char *dest, int destsize, const char *name, const char *
/* first 6 bytes of selfkey */
char self_id[32] = {0};
path_len += KEY_IDENT_DIGITS * 2;
path_len += KEY_IDENT_BYTES;
sprintf(&self_id[0], "%02X", selfkey[0] & 0xff);
sprintf(&self_id[2], "%02X", selfkey[1] & 0xff);
sprintf(&self_id[4], "%02X", selfkey[2] & 0xff);
self_id[KEY_IDENT_DIGITS * 2] = '\0';
self_id[KEY_IDENT_BYTES] = '\0';
char other_id[32] = {0};
if (otherkey) {
/* first 6 bytes of otherkey */
path_len += KEY_IDENT_DIGITS * 2;
path_len += KEY_IDENT_BYTES;
sprintf(&other_id[0], "%02X", otherkey[0] & 0xff);
sprintf(&other_id[2], "%02X", otherkey[1] & 0xff);
sprintf(&other_id[4], "%02X", otherkey[2] & 0xff);
other_id[KEY_IDENT_DIGITS * 2] = '\0';
other_id[KEY_IDENT_BYTES] = '\0';
}
if (path_len >= destsize) {

View File

@ -477,10 +477,9 @@ on_error:
returns length of msg, which will be no larger than size-1 */
size_t copy_tox_str(char *msg, size_t size, const char *data, size_t length)
{
size_t i;
size_t j = 0;
for (i = 0; (i < length) && (j < size - 1); ++i) {
for (size_t i = 0; (i < length) && (j < size - 1); ++i) {
if (data[i] != '\r') {
msg[j++] = data[i];
}

View File

@ -175,9 +175,7 @@ static int add_friend_request(const char *public_key, const char *data)
return -1;
}
int i;
for (i = 0; i <= FrndRequests.max_idx; ++i) {
for (int i = 0; i <= FrndRequests.max_idx; ++i) {
if (!FrndRequests.request[i].active) {
FrndRequests.request[i].active = true;
memcpy(FrndRequests.request[i].key, public_key, TOX_PUBLIC_KEY_SIZE);
@ -526,6 +524,26 @@ static void prompt_onConnectionChange(ToxWindow *self, Tox *m, uint32_t friendnu
}
}
/**
* Return true is the first 3 bytes of `key` are identical to any other contact in the contact list.
*/
static bool key_is_similar(const char *key)
{
for (size_t i = 0; i < Friends.max_idx; ++i) {
const ToxicFriend *friend = &Friends.list[i];
if (!friend->active) {
continue;
}
if (memcmp(friend->pub_key, key, KEY_IDENT_BYTES / 2) == 0) {
return true;
}
}
return false;
}
static void prompt_onFriendRequest(ToxWindow *self, Tox *m, const char *key, const char *data, size_t length)
{
UNUSED_VAR(m);
@ -536,6 +554,13 @@ static void prompt_onFriendRequest(ToxWindow *self, Tox *m, const char *key, con
line_info_add(self, true, NULL, NULL, SYS_MSG, 0, 0, "Friend request with the message '%s'", data);
write_to_log("Friend request with the message '%s'", "", ctx->log, true);
if (key_is_similar(key)) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED,
"WARNING: This contact's public key is suspiciously similar to that of another contact ");
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED,
"in your list. This may be an impersonation attempt, or it may have occurred by chance.");
}
int n = add_friend_request(key, data);
if (n == -1) {

View File

@ -23,6 +23,10 @@
#ifndef TOXIC_H
#define TOXIC_H
#ifndef NCURSES_WIDECHAR
#define NCURSES_WIDECHAR 1
#endif
#ifndef TOXICVER
#define TOXICVER "NOVERS" /* Use the -D flag to set this */
#endif
@ -46,7 +50,7 @@
#define MAX_STR_SIZE TOX_MAX_MESSAGE_LENGTH /* must be >= TOX_MAX_MESSAGE_LENGTH */
#define MAX_CMDNAME_SIZE 64
#define TOXIC_MAX_NAME_LENGTH 32 /* Must be <= TOX_MAX_NAME_LENGTH */
#define KEY_IDENT_DIGITS 3 /* number of hex digits to display for the pub-key based identifier */
#define KEY_IDENT_BYTES 6 /* number of hex digits to display for the public key identifier */
#define TIME_STR_SIZE 32
#define COLOR_STR_SIZE 10 /* should fit every color option */