summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton <anton@picapica>2018-07-20 02:17:54 +0400
committerAnton <anton@picapica>2018-07-20 02:17:54 +0400
commitfd9f68b50ef480f84bda3910e6e2a064eeaaee51 (patch)
tree359a34cd150eb332ffab2c8eb597231330d4f956
parent5ddb7da72261dc916128f5a3f5865d1cdb16a0f1 (diff)
downloadpica-pica-fd9f68b50ef480f84bda3910e6e2a064eeaaee51.tar.gz
pica-pica-fd9f68b50ef480f84bda3910e6e2a064eeaaee51.zip
comments
-rw-r--r--PICA_client.c168
-rw-r--r--PICA_client.h100
-rw-r--r--PICA_msgproc.h12
-rw-r--r--PICA_node.c47
-rw-r--r--PICA_proto.h2
5 files changed, 99 insertions, 230 deletions
diff --git a/PICA_client.c b/PICA_client.c
index 7b3413a..3829f49 100644
--- a/PICA_client.c
+++ b/PICA_client.c
@@ -22,7 +22,7 @@
#include <openssl/dh.h>
#include <string.h>
-#define PICA_DEBUG // debug
+#define PICA_DEBUG
#ifdef PICA_DEBUG
#define PICA_TRACEFUNC fprintf(stderr, "%s()\n", __PRETTY_FUNCTION__);
@@ -30,11 +30,6 @@
#define PICA_TRACEFUNC
#endif
-//static SSL_CTX* ctx;
-//unsigned char __hellomsg[4]={0xCA,0xCA,PICA_PROTO_VER_HIGH,PICA_PROTO_VER_LOW};
-
-//char _msgbuf[65536];//
-
static struct PICA_client_callbacks callbacks;
#ifdef PICA_MULTITHREADED
@@ -43,7 +38,8 @@ static struct PICA_client_callbacks callbacks;
static HANDLE *mt_locks;
const char *PICA_inet_ntop(int af, const void *src, char *dst, size_t size);
-#define inet_ntop PICA_inet_ntop //own implementation of inet_ntop() for WinXP compatibility
+/* own implementation of inet_ntop() for WinXP compatibility */
+#define inet_ntop PICA_inet_ntop
#else
static pthread_mutex_t *mt_locks;
@@ -105,7 +101,7 @@ const struct PICA_msginfo c2n_messages[] =
{PICA_PROTO_PINGREQ, PICA_MSG_FIXED_SIZE, PICA_PROTO_PINGREQ_SIZE, procmsg_PINGREQ},
{PICA_PROTO_INITRESPOK, PICA_MSG_FIXED_SIZE, PICA_PROTO_INITRESPOK_SIZE, procmsg_INITRESP},
{PICA_PROTO_VERDIFFER, PICA_MSG_FIXED_SIZE, PICA_PROTO_VERDIFFER_SIZE, procmsg_INITRESP}
-};//---!!! PING!!!
+};
const struct PICA_msginfo c2c_messages[] =
{
@@ -129,45 +125,6 @@ struct PICA_msginfo c2c_init_messages[] =
};
-// static int pem_passwd_cb(char *buf, int size, int rwflag, void *userdata)
-//{
-//strncpy(buf, (char *)(userdata), size);
-//buf[size - 1] = 0;
-//return(strlen(buf));
-//}
-/*
-//функция возвращает номер клиента id в бинарном виде, извлекая его из строки,
-//которая возвращается функцией X509_NAME_oneline и представляет собой DN из сертификата клиента
- static int get_id_fromsubjstr(char* DN_str,unsigned int* id)
-{
-char* tmp1;
-char* tmp2;
-
-tmp1=strstr(DN_str,"/CN=");
-
-if (!tmp1)
- return 0;
-
-tmp2=strchr(tmp1,'#');
-
-if (!tmp2)
- return 0;
-
-*tmp2=0;
-
-tmp1+=4;
-
-if (tmp1==tmp2)
- return 0;
-
-*id=(unsigned int)strtol(tmp1,0,10);
-
-*tmp2='#';
-return 1;
-}
-*/
-
-
int PICA_get_id_from_cert_file(const char *cert_file, unsigned char *id)
{
X509 *x;
@@ -300,13 +257,13 @@ static int c2c_stage2_connid(struct PICA_c2c *chnl)
{
if (chnl->outgoing)
{
- memcpy(mp->tail, chnl->acc->id, PICA_ID_SIZE);//вызвывающий
- memcpy(mp->tail + PICA_ID_SIZE, chnl->peer_id, PICA_ID_SIZE);//вызываемый
+ memcpy(mp->tail, chnl->acc->id, PICA_ID_SIZE);/* caller ID*/
+ memcpy(mp->tail + PICA_ID_SIZE, chnl->peer_id, PICA_ID_SIZE);/* callee ID*/
}
else
{
- memcpy(mp->tail, chnl->peer_id, PICA_ID_SIZE);//вызвывающий
- memcpy(mp->tail + PICA_ID_SIZE, chnl->acc->id, PICA_ID_SIZE);//вызываемый
+ memcpy(mp->tail, chnl->peer_id, PICA_ID_SIZE);/* caller ID*/
+ memcpy(mp->tail + PICA_ID_SIZE, chnl->acc->id, PICA_ID_SIZE);/* callee ID*/
}
chnl->state = PICA_C2C_STATE_CONNID;
@@ -363,8 +320,6 @@ static int c2c_stage3_starttls(struct PICA_c2c *chnl)
static int c2c_verify_peer_cert(struct PICA_c2c *chnl)
{
-//проверить сертификат собеседника
-
chnl->peer_cert = SSL_get_peer_certificate(chnl->ssl);
if (!chnl->peer_cert)
@@ -734,7 +689,7 @@ static unsigned int procmsg_CONNREQINC(unsigned char* buf, unsigned int nb, void
ret = c2n_alloc_c2c( ci, &_chnl, peer_id, PICA_C2C_INCOMING);
if (!ret)
- return 0; //ERR_CHECK - кончилась память
+ return 0;
do
{
@@ -1311,21 +1266,6 @@ static int check_pkey_passphrase(const char *pkey_file,
}
-
-// Opens socket to listen for incoming direct c2c connections bypassing nodes
-//
-// acc - pointer to opened account
-//
-// public_addr - DNS name or IP address string,
-// it is an address that will be used for connecting from global Internet.
-// Should be set to router's external IP if computer running pica-client is located behind the NAT.
-//
-// public_port - TCP port for incoming connections from global Internet
-//
-// local_port - TCP port that will be actually opened on computer listening for direct c2c connections
-//
-// l - address of pointer that will be filled with address of created PICA_listener structure
-//
int PICA_new_listener(const struct PICA_acc *acc, const char *public_addr, int public_port, int local_port, struct PICA_listener **l)
{
int ret, ret_err, flag;
@@ -1469,7 +1409,6 @@ int PICA_open_acc(const char *cert_file,
goto error_ret_2;
}
-////<<
if (password_cb)
{
SSL_CTX_set_default_passwd_cb(a->ctx, password_cb);
@@ -1490,11 +1429,6 @@ int PICA_open_acc(const char *cert_file,
ret_err = PICA_ERRSSL;
goto error_ret_2;
}
-////<<
-
-//ret=SSL_CTX_load_verify_locations(cid->ctx,CA_file,0/*"trustedCA/"*/);
-//printf("loadverifylocations ret=%i\n",ret);//debug
-//SSL_CTX_set_client_CA_list(cid->ctx,SSL_load_client_CA_file(CA_file));
ret = SSL_CTX_set_cipher_list(a->ctx, "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CAMELLIA256-SHA");
@@ -1617,21 +1551,6 @@ static int directc2c_stage2_starttls(struct PICA_directc2c *d, struct PICA_c2c *
return PICA_OK;
}
-/*адрес сервера, сертификат клиента и закрытый ключ*/
-
-//Осуществляет подключение к серверу по указанному адресу.
-//Аргументы:
-//nodeaddr - адрес узла
-//port - номер порта, в нативном для хост-машины порядке байт
-//CA_file - имя файла, содержащего корневой сертификат в формате PEM
-//cert_file - имя файла, содержащего сертфикат клиента в формате PEM
-//pkey_file - имя файла, содержащего приватный ключ в формате PEM
-//password_cb - callback-функция, запрашивающая пароль к приватному ключу, см. man 3 SSL_CTX_set_default_passwd_cb;в userdata передается указатель на id
-//ci -указатель на указатель на структуру PICA_c2n, который будет проинициализирован при успешном выполнении функции
-//Память, выделенная под структуру, освобождается при вызове PICA_close_c2n
-//Возвращаемое значение - код завершения
-//PICA_OK - успешное завершение функции
-//....
int PICA_new_c2n(const struct PICA_acc *acc, const char *nodeaddr, unsigned int port,
enum PICA_directc2c_config direct_c2c_mode, int multilogin,
@@ -1723,7 +1642,6 @@ int PICA_new_c2n(const struct PICA_acc *acc, const char *nodeaddr, unsigned int
cid->state = PICA_C2N_STATE_CONNECTING;
ret = connect(cid->sck_comm, (struct sockaddr*)&cid->srv_addr, sizeof(cid->srv_addr));
-/////////////////state_
if (ret == 0)
return c2n_stage2_sendreq(cid);
@@ -1731,72 +1649,8 @@ int PICA_new_c2n(const struct PICA_acc *acc, const char *nodeaddr, unsigned int
if ((ret_err = process_first_async_connect_result(ret)) != PICA_OK)
goto error_ret_4;
-
- /*
- do
- {
- ret = PICA_write_c2n(cid);
- if (ret != PICA_OK)
- {
- ret_err = ret;
- break;
- }
- ret = PICA_read_c2n(cid);
- if (ret != PICA_OK)
- {
- ret_err = ret;
- break;
- }
- //TODO Timeout
- }
- while (cid->init_resp_ok == 0);
-
- if (cid->init_resp_ok != 1)
- {
- if (cid->init_resp_ok == -1)
- {
- if (cid->node_ver_major > PICA_PROTO_VER_HIGH ||
- (cid->node_ver_major == PICA_PROTO_VER_HIGH && cid->node_ver_minor > PICA_PROTO_VER_LOW))
- ret_err = PICA_ERRPROTONEW;
- else
- ret_err = PICA_ERRPROTOOLD;
- }
- goto error_ret_4;
- }
-
- //printf("6\n");//debug
- */ /*
-ret=SSL_set_fd(cid->ssl_comm,cid->sck_comm);
-
-//printf("SSL_set_fd=%i\n",ret);
-
-ret=SSL_accept(cid->ssl_comm);
-/////////////////state_
-cid->state = PICA_C2N_STATE_WAITINGTLS;
-if (ret!=1)
-{
-//printf("SSL_accept ret=%i\n SSL_get_error=%i\n",ret,SSL_get_error(cid->ssl_comm,ret));//debug
-//ERR_CHECK
-ret_err=PICA_ERRSSL;
-goto error_ret_4;
-}*/ /*
-cid->state = PICA_C2N_STATE_CONNECTED;//<<<!!!
-
-{
-struct PICA_proto_msg *mp;
-
-mp = c2n_writebuf_push( cid, PICA_PROTO_CLNODELISTREQ, PICA_PROTO_CLNODELISTREQ_SIZE);
-
-if (mp)
-{
-RAND_pseudo_bytes(mp->tail, 2);
-}
-}
-*/
-
return PICA_OK;
-
error_ret_4: //(4)
SHUTDOWN(cid->sck_comm);
CLOSE(cid->sck_comm);
@@ -1815,9 +1669,6 @@ error_ret_1: //(1)
}
-
-//создает ИСХОДЯЩИЙ логический зашифрованный канал связи с указанным собеседником, если тот доступен
-// в данный момент.
int PICA_new_c2c(struct PICA_c2n *ci, const unsigned char *peer_id, struct PICA_listener *l, struct PICA_c2c **chn)
{
PICA_TRACEFUNC
@@ -2884,7 +2735,6 @@ int PICA_read_c2c(struct PICA_c2c *chn)
return ret;
}
-//функция читает и обрабатывает данные, приходящие от сервера по управляющему соединению.
int PICA_read_c2n(struct PICA_c2n *ci)
{
int ret;
diff --git a/PICA_client.h b/PICA_client.h
index efa035f..cef9fae 100644
--- a/PICA_client.h
+++ b/PICA_client.h
@@ -140,7 +140,10 @@ struct PICA_c2c;
struct PICA_acc
{
- unsigned char id[PICA_ID_SIZE]; //SHA224 hash of user's certificate in DER format
+ /**
+ * SHA224 hash of user's certificate in DER format
+ */
+ unsigned char id[PICA_ID_SIZE];
SSL_CTX* ctx;
};
@@ -165,12 +168,9 @@ struct PICA_c2n
struct PICA_acc *acc;
//#warning "sockaddr!"
struct sockaddr_in srv_addr; // sockaddr !!
-//unsigned char id[PICA_ID_SIZE]; //SHA224 hash of user's certificate in DER format
-//SSL_CTX* ctx;
SOCKET sck_comm;
SSL* ssl_comm;
-
enum PICA_c2n_state state;
enum PICA_directc2c_config directc2c_config;
int multilogin_policy;
@@ -242,16 +242,15 @@ struct PICA_directc2c
struct PICA_c2c
{
const struct PICA_acc *acc;
- struct PICA_c2n *conn;//соединение с сервером, через которое установлен данный логический канал связи
+ struct PICA_c2n *conn;
unsigned char peer_id[PICA_ID_SIZE];
SOCKET sck_data;
SSL *ssl;
struct PICA_directc2c *direct;
- int outgoing;//1 если создание канала инициировано локальным клиентом, 0 - если собеседником
+ int outgoing;
X509 *peer_cert;
-//unsigned char msgbuf[PICA_CHNMSGBUFLEN];
unsigned char *read_buf;
unsigned char *write_buf;
@@ -274,7 +273,10 @@ struct PICA_c2c
uint64_t recvfile_size;
uint64_t recvfile_pos;
FILE *recvfile_stream;
-//this flag should be set when connection must be closed after sending last pushed packet
+
+ /** this flag should be set when connection
+ * must be closed after sending last pushed packet
+ */
int disconnect_on_empty_write_buf;
int switched_to_directc2c_write;
int switched_to_directc2c_read;
@@ -299,26 +301,60 @@ struct PICA_listener
struct PICA_client_callbacks
{
-//получение сообщения.
+ /**
+ * New text message received
+ */
void (*newmsg_cb)(const unsigned char *peer_id, const char* msgbuf, unsigned int nb, int type);
-//получение подтверждения о доставке сообщения
+ /**
+ * Message delivery confirmed
+ */
void (*msgok_cb)(const unsigned char *peer_id);
-//создание канала с собеседником
+ /**
+ * Client-to-client connection established
+ */
void (*c2c_established_cb)(const unsigned char *peer_id);
-//создать канал не удалось
+ /**
+ * Failed to establish client-to-client connection
+ */
void (*c2c_failed_cb)(const unsigned char *peer_id);
-//входящий запрос на создание канала от пользователя с номером caller_id
-//возвращаемое значение: 0 - отклонить запрос, ненулевое значение - принять запрос
+ /** Received incoming client-to-client connection request
+ \return action to perform
+ \retval 0 - reject request
+ \retval non-zero - accept request
+ */
int (*accept_cb)(const unsigned char *caller_id);
-//запрошенный пользователь не найден, в оффлайне или отказался от общения
+ /**
+ * Requested client is unavailable or rejected request
+ */
void (*notfound_cb)(const unsigned char *callee_id);
-//
+ /**
+ * Client-to-client connection is closed
+ */
void (*c2c_closed_cb)(const unsigned char *peer_id, int reason);
-
+ /**
+ * Received list of node addresses. Callback is called for
+ * each node address entry.
+ * \param type address type, PICA_PROTO_NEWNODE_{IPV4,IPV6,DNS}
+ * \param addr_bin address in binary form, IPv4 or IPv6 in network byte order, DNS - zero-terminated string, same as addr_str
+ * \param addr_str address in string format, zero-terminated
+ * \param port listening port of node, in host byte order
+ */
void (*nodelist_cb)(int type, void *addr_bin, const char *addr_str, unsigned int port);
-//сертификат собеседника в формате PEM. Функция должна сравнить предъявленный сертификат с сохранённым (если есть) и вернуть 1 при успешной проверке, 0 - при неуспешной
+ /**
+ * Peer'c certificate in PEM format. Callback must compare passed cert with
+ * previously stored cert of this peer (if it exists).
+ * \return verification result
+ * \retval 1 - verification success
+ * \retval 0 - verification failed
+ */
int (*peer_cert_verify_cb)(const unsigned char *peer_id, const char *cert_pem, unsigned int nb);
-// returns 0 if file is rejected, 1 if accepted, 2 if decision is postponed
+ /**
+ * Received request of file transfer.
+ * \return action to perform
+ * \retval 0 - reject file
+ * \retval 1 - accept file
+ * \retval 2 - postpone decision. File can be accepted later by calling PICA_accept_file()
+ */
int (*accept_file_cb)(const unsigned char *peer_id, uint64_t file_size, const char *filename, unsigned int filename_size);
void (*accepted_file_cb)(const unsigned char *peer_id);
@@ -346,27 +382,41 @@ struct PICA_client_callbacks
extern "C" {
#endif
-//read certificate from cert_file in PEM format, store id in buffer pointed by id
+/**
+ * Read certificate from cert_file in PEM format, store id in buffer pointed by id
+ * \param [in] cert_file string with certificate file name
+ * \param [out] id buffer to store ID, PICA_ID_SIZE octets
+ */
int PICA_get_id_from_cert_file(const char *cert_file, unsigned char *id);
-//read certificate from C string in PEM format, store id in buffer pointed by id
+/**
+ * Read certificate from C string in PEM format, store id in buffer pointed by id.
+ * \param [in] cert_pem - certificate in PEM format
+ * \param [out] id buffer to store ID, PICA_ID_SIZE octets
+ */
int PICA_get_id_from_cert_string(const char *cert_pem, unsigned char *id);
int PICA_client_init(struct PICA_client_callbacks *clcbs);
-
int PICA_new_c2n(const struct PICA_acc *acc, const char *nodeaddr, unsigned int port,
enum PICA_directc2c_config direct_c2c_mode, int multilogin,
struct PICA_listener *l, struct PICA_c2n **ci);
int PICA_new_c2c(struct PICA_c2n *ci, const unsigned char *peer_id, struct PICA_listener *l, struct PICA_c2c **chn);
-
+ /**
+ * Opens socket to listen for incoming direct c2c connections bypassing nodes
+ * \param acc - pointer to opened account instance
+ * \param public_addr - DNS name or IP address string,
+ * it is an address that will be used for connecting from global Internet.
+ * Should be set to router's external IP if computer running pica-client is located behind the NAT.
+ * \param public_port - TCP port for incoming connections from global Internet
+ * \param local_port - TCP port that will be actually opened on computer listening for direct c2c connections
+ * \param l - address of pointer that will be filled with address of created PICA_listener structure
+ */
int PICA_new_listener(const struct PICA_acc *acc, const char *public_addr, int public_port, int local_port, struct PICA_listener **l);
-// <<<////
int PICA_open_acc(const char *cert_file,
const char *pkey_file,
const char *dh_param_file,
int (*password_cb)(char *buf, int size, int rwflag, void *userdata),
struct PICA_acc **acc);
-// <<<////
//connections, listeners - NULL-terminated arrays of pointers to appropriate structures
// timeout - timeout in milliseconds
diff --git a/PICA_msgproc.h b/PICA_msgproc.h
index 4382d2a..551d3de 100644
--- a/PICA_msgproc.h
+++ b/PICA_msgproc.h
@@ -15,8 +15,7 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-// структуры и функции для обработки сообщений протокола
-//
+
#ifndef PICA_MSGPROC_H
#define PICA_MSGPROC_H
@@ -28,9 +27,12 @@
struct PICA_msginfo
{
unsigned int msgid;
- unsigned int fixedsz;//фиксированный или переменный размер
- unsigned int sz;//фиксированный размер всего пакета либо кол-во байт, определяющих размер хвостовой части пакета
- unsigned int (*msgprocfn)(unsigned char*, unsigned int, void*); //функция-обработчик данного типа сообщений
+ /* PICA_MSG_FIXED_SIZE if message has fixed size, PICA_MSG_VAR_SIZE in case of variable size */
+ unsigned int fixedsz;
+ /* Size of the whole message in case of fixed-size message or number of octets that store size of the message */
+ unsigned int sz;
+ /* Pointer to message handler */
+ unsigned int (*msgprocfn)(unsigned char*, unsigned int, void*);
};
unsigned int PICA_msggetsize(unsigned char *buf, unsigned int nb, struct PICA_msginfo *msgs, unsigned int nmsg);
diff --git a/PICA_node.c b/PICA_node.c
index 6c462ba..e27364f 100644
--- a/PICA_node.c
+++ b/PICA_node.c
@@ -15,8 +15,7 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-//Программа является узлом сети
-//
+
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
@@ -55,9 +54,9 @@ typedef u_short uint16_t;
time_t skynet_refresh_tmst;
-clock_t TMO_CCLINK_WAITACTIVE = 15; //CONF //таймаут ожидания перехода соединения в активное состояние
+clock_t TMO_CCLINK_WAITACTIVE = 15; //CONF
-char *my_addr;//TEMP CONF FIXME собственный ip-адрес узла, на котором он ожидает соединения
+char *my_addr;//TEMP CONF FIXME
SOCKET listen_comm_sck;//*
@@ -66,9 +65,9 @@ struct newconn newconns[MAX_NEWCONNS];
unsigned int newconns_pos = 0;
-struct client *client_tree_root;//корень дерева клиентов
-struct client *client_list_head;//указатель на первый элемент списка клиентов или 0, если список пуст
-struct client *client_list_end;//указатель на последний элемент списка клиентов или 0, если список пуст
+struct client *client_tree_root;
+struct client *client_list_head;
+struct client *client_list_end;
struct cclink *cclink_list_head;
struct cclink *cclink_list_end;
@@ -140,7 +139,6 @@ struct newconn* newconn_add(struct newconn *ncs, int *pos);
void PICA_node_joinskynet(const char* addrlistfilename, const char *my_addr);
-//описание формата сообщений, которые могут приходить _ОТ_ клиентов по управляющему защищенному соединению
#define MSGINFO_MSGSNUM(arr) (sizeof(arr)/sizeof(struct PICA_msginfo))
struct PICA_msginfo _msginfo_comm[] =
@@ -1404,37 +1402,7 @@ int PICA_node_init()
return 1;
}
-/*
-//функция возвращает номер клиента id в бинарном виде, извлекая его из строки,
-//которая возвращается функцией X509_NAME_oneline и представляет собой DN из сертификата клиента
-int get_id_fromsubjstr(char* DN_str,unsigned int* id)
-{
-char* tmp1;
-char* tmp2;
-
-tmp1=strstr(DN_str,"/CN=");
-
-if (!tmp1)
- return 0;
-
-tmp2=strchr(tmp1,'#');
-
-if (!tmp2)
- return 0;
-*tmp2=0;
-
-tmp1+=4;
-
-if (tmp1==tmp2)
- return 0;
-
-*id=(unsigned int)strtol(tmp1,0,10);
-
-*tmp2='#';
-return 1;
-}
-*/
void newconn_close(struct newconn* nc)
{
@@ -1579,7 +1547,7 @@ void client_tree_print(struct client *c)
client_tree_print(c->right);
}
-//удаление структуры из дерева
+
void client_tree_remove(struct client* ci)
{
struct client** p_link;//указывает на left или right в родительском узле
@@ -1930,7 +1898,6 @@ struct nodelink *nodelink_search_by_ipv4addr(in_addr_t ip, in_port_t port)
return nl;
}
-// обработка различных таймаутов. Отправка пингов
void process_timeouts_newconn()
{
diff --git a/PICA_proto.h b/PICA_proto.h
index 6cb704f..b218c19 100644
--- a/PICA_proto.h
+++ b/PICA_proto.h
@@ -15,7 +15,7 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-//коды сообщений протокола и структура сообщения
+/* Protocol definitions */
#ifndef PICA_PROTO_H
#define PICA_PROTO_H