diff options
| author | Anton <anton@picapica> | 2018-07-20 02:17:54 +0400 |
|---|---|---|
| committer | Anton <anton@picapica> | 2018-07-20 02:17:54 +0400 |
| commit | fd9f68b50ef480f84bda3910e6e2a064eeaaee51 (patch) | |
| tree | 359a34cd150eb332ffab2c8eb597231330d4f956 | |
| parent | 5ddb7da72261dc916128f5a3f5865d1cdb16a0f1 (diff) | |
| download | pica-pica-fd9f68b50ef480f84bda3910e6e2a064eeaaee51.tar.gz pica-pica-fd9f68b50ef480f84bda3910e6e2a064eeaaee51.zip | |
comments
| -rw-r--r-- | PICA_client.c | 168 | ||||
| -rw-r--r-- | PICA_client.h | 100 | ||||
| -rw-r--r-- | PICA_msgproc.h | 12 | ||||
| -rw-r--r-- | PICA_node.c | 47 | ||||
| -rw-r--r-- | PICA_proto.h | 2 |
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 |
