|
|
|
@ -480,13 +480,14 @@ static void *__sntll_thread(void *b)
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* FIXME: AWARE coc and co - fix it */
|
|
|
|
|
int connection_create_fapi_m(conn_sys_t *ssys, conn_t *co, int sck,
|
|
|
|
|
struct in_addr *addr)
|
|
|
|
|
{
|
|
|
|
|
void *buf = NULL;
|
|
|
|
|
char *bbuf;
|
|
|
|
|
conn_t *coc = __connection_minimal_alloc(addr);
|
|
|
|
|
sx_msg_t *msg = NULL;
|
|
|
|
|
sxmsg_t *msg = NULL;
|
|
|
|
|
sntllv2_head_t *head;
|
|
|
|
|
sntllv2_bundle_t *bundle;
|
|
|
|
|
size_t rd;
|
|
|
|
@ -547,9 +548,9 @@ int connection_create_fapi_m(conn_sys_t *ssys, conn_t *co, int sck,
|
|
|
|
|
buf = mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
|
|
|
|
if(buf == MAP_FAILED) { r = SNE_ENOMEM; goto __fail2; }
|
|
|
|
|
/* allocate first message */
|
|
|
|
|
if(!(msg = malloc(sizeof(sx_msg_t)))) { r = SNE_ENOMEM; goto __fail2; }
|
|
|
|
|
if(!(msg = malloc(sizeof(sxmsg_t)))) { r = SNE_ENOMEM; goto __fail2; }
|
|
|
|
|
else {
|
|
|
|
|
memset(msg, 0, sizeof(sx_msg_t));
|
|
|
|
|
memset(msg, 0, sizeof(sxmsg_t));
|
|
|
|
|
coc->messages[0] = msg;
|
|
|
|
|
}
|
|
|
|
|
bbuf = (char *)buf;
|
|
|
|
@ -641,3 +642,195 @@ int connection_create_fapi_m(conn_sys_t *ssys, conn_t *co, int sck,
|
|
|
|
|
close(sck);
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
conn_t *connection_link(conn_sys_t *ssys, const char *host,
|
|
|
|
|
int port, const char *SSL_cert, const char *login,
|
|
|
|
|
const char *passwd)
|
|
|
|
|
{
|
|
|
|
|
conn_t *co = __connection_minimal_alloc(addr);
|
|
|
|
|
struct hostent *host_;
|
|
|
|
|
struct sockaddr_in addr;
|
|
|
|
|
int r = SNE_SUCCESS, sck;
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
WSADATA wsaData;
|
|
|
|
|
#endif
|
|
|
|
|
char hostbuf[2048];
|
|
|
|
|
void *buf = NULL;
|
|
|
|
|
char *bbuf;
|
|
|
|
|
sntllv2_head_t *head;
|
|
|
|
|
sntllv2_bundle_t *bundle;
|
|
|
|
|
size_t rd;
|
|
|
|
|
|
|
|
|
|
r = SNE_IGNORED;
|
|
|
|
|
if(!host || !SSL_cert) goto __fail;
|
|
|
|
|
if(!co) { r = SNE_ENOMEM; goto __fail; }
|
|
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
WSAStartup(MAKEWORD(2, 2), &wsaData);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* ok, now we need to init ssl stuff */
|
|
|
|
|
co->ssys = ssys;
|
|
|
|
|
|
|
|
|
|
/* init SSL certificates and context */
|
|
|
|
|
co->ctx = SSL_CTX_new(TLSv1_2_client_method());
|
|
|
|
|
if(!co->ctx) { r = SNE_ENOMEM; goto __fail; }
|
|
|
|
|
else {
|
|
|
|
|
/* set verify context */
|
|
|
|
|
SSL_CTX_set_verify(co->ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
|
|
|
|
|
__verify_certcall_dummy);
|
|
|
|
|
/* set verify depth */
|
|
|
|
|
SSL_CTX_set_verify_depth(co->ctx, VERIFY_DEPTH);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* load certificates */
|
|
|
|
|
SSL_CTX_load_verify_locations(co->ctx, ssys->rootca, NULL);
|
|
|
|
|
/* set the local certificate from CertFile */
|
|
|
|
|
if(SSL_CTX_use_certificate_file(co->ctx, SSL_cert,
|
|
|
|
|
SSL_FILETYPE_PEM)<=0) {
|
|
|
|
|
ERR_print_errors_fp(stderr);
|
|
|
|
|
r = SNE_ESSL;
|
|
|
|
|
goto __fail;
|
|
|
|
|
}
|
|
|
|
|
/* set the private key from KeyFile (may be the same as CertFile) */
|
|
|
|
|
if(SSL_CTX_use_PrivateKey_file(co->ctx, SSL_cert,
|
|
|
|
|
SSL_FILETYPE_PEM)<=0) {
|
|
|
|
|
r = SNE_ESSL;
|
|
|
|
|
goto __fail;
|
|
|
|
|
}
|
|
|
|
|
/* verify private key */
|
|
|
|
|
if (!SSL_CTX_check_private_key(co->ctx)) {
|
|
|
|
|
r = SNE_ESSL;
|
|
|
|
|
goto __fail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* resolve host */
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
host_ = gethostbyname(host);
|
|
|
|
|
#else
|
|
|
|
|
r = __resolvehost(host, hostbuf, 2048, &host_);
|
|
|
|
|
#endif
|
|
|
|
|
if(r) {
|
|
|
|
|
r = SNE_FAILED;
|
|
|
|
|
goto __fail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* create a socket */
|
|
|
|
|
sck = socket(PF_INET, SOCK_STREAM, 0);
|
|
|
|
|
bzero(&addr, sizeof(addr));
|
|
|
|
|
|
|
|
|
|
/* try to connect it */
|
|
|
|
|
addr.sin_family = AF_INET;
|
|
|
|
|
addr.sin_port = htons(port);
|
|
|
|
|
addr.sin_addr.s_addr = *(uint32_t*)(host_->h_addr);
|
|
|
|
|
r = connect(sck, (struct sockaddr*)&addr, sizeof(addr));
|
|
|
|
|
if(r) {
|
|
|
|
|
close(sck);
|
|
|
|
|
r = SNE_FAILED; /* couldn't connect to the desired host */
|
|
|
|
|
goto __fail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* SSL handshake */
|
|
|
|
|
co->ssl = SSL_new(co->ctx); /* TODO: checkout for it */
|
|
|
|
|
SSL_set_fd(co->ssl, sck); /* attach connected socket */
|
|
|
|
|
SSL_set_connect_state(co->ssl);
|
|
|
|
|
if(SSL_connect(co->ssl) == -1) {
|
|
|
|
|
r = SNE_EPERM;
|
|
|
|
|
/* shutdown connection */
|
|
|
|
|
goto __fail;
|
|
|
|
|
} /* if success we're ready to use established SSL channel */
|
|
|
|
|
|
|
|
|
|
/* set connection to the batch mode */
|
|
|
|
|
co->flags |= SNSX_BATCHMODE;
|
|
|
|
|
|
|
|
|
|
/* allocate our first buffer */
|
|
|
|
|
buf = mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
|
|
|
|
if(buf == MAP_FAILED) { r = SNE_ENOMEM; goto __fail2; }
|
|
|
|
|
/* allocate first message */
|
|
|
|
|
if(!(msg = malloc(sizeof(sxmsg_t)))) { r = SNE_ENOMEM; goto __fail2; }
|
|
|
|
|
else {
|
|
|
|
|
memset(msg, 0, sizeof(sxmsg_t));
|
|
|
|
|
co->messages[0] = msg;
|
|
|
|
|
}
|
|
|
|
|
bbuf = (char *)buf;
|
|
|
|
|
bbuf += sizeof(sntllv2_head_t);
|
|
|
|
|
head = (sntllv2_head_t *)buf;
|
|
|
|
|
|
|
|
|
|
sexp_t *sx;
|
|
|
|
|
size_t ln;
|
|
|
|
|
while(co->flags & SNSX_BATCHMODE) {
|
|
|
|
|
/* form a message -- credentials */
|
|
|
|
|
ln = snprintf(bbuf, 65535 - sizeof(sntllv2_head_t), "(auth-set-credentials \"%s\" \"%s\")",
|
|
|
|
|
login ? login : "nil", passwd ? passwd : "nil");
|
|
|
|
|
head->opcode = SNE_SUCCESS;
|
|
|
|
|
head->payload_length = ln;
|
|
|
|
|
wr = __conn_write(co, buf, ln + sizeof(sntllv2_head_t));
|
|
|
|
|
if(wr < 0) goto __fail2;
|
|
|
|
|
|
|
|
|
|
rd = __conn_read(co, head, sizeof(sntllv2_head_t));
|
|
|
|
|
if(rd < 0) goto __fail2;
|
|
|
|
|
if(head->opcode != SNE_SUCCESS) goto __fail2;
|
|
|
|
|
|
|
|
|
|
/* ok, get available channels */
|
|
|
|
|
head->opcode = SNE_SUCCESS;
|
|
|
|
|
head->payload_length = ln;
|
|
|
|
|
ln = snprintf(bbuf, 65535 - sizeof(sntllv2_head_t), "(get-channels-list)");
|
|
|
|
|
wr = __conn_write(co, buf, ln + sizeof(sntllv2_head_t));
|
|
|
|
|
if(wr < 0) goto __fail2;
|
|
|
|
|
|
|
|
|
|
rd = __conn_read(co, head, sizeof(sntllv2_head_t));
|
|
|
|
|
if(rd < 0) goto __fail2;
|
|
|
|
|
if(head->opcode != SNE_SUCCESS) goto __fail2;
|
|
|
|
|
if(!head->payload_length) goto __fail2;
|
|
|
|
|
rd = __conn_read(co, bbuf, head->payload_length);
|
|
|
|
|
if(rd < 0) goto __fail2;
|
|
|
|
|
|
|
|
|
|
/* perform a parsing of the desired message */
|
|
|
|
|
bbuf[rd] = '\0';
|
|
|
|
|
sx = parse_sexp(bbuf, rd);
|
|
|
|
|
r = __eval_syssexp(co, sx);
|
|
|
|
|
destroy_sexp(sx);
|
|
|
|
|
head->opcode = r;
|
|
|
|
|
head->payload_length = 0;
|
|
|
|
|
wr = __conn_write(co, head, sizeof(sntllv2_head_t));
|
|
|
|
|
if(wr < 0) goto __fail2;
|
|
|
|
|
if(r != SNE_SUCCESS) goto __fail2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* if we're there - negotiation is done, going to init messaging mode */
|
|
|
|
|
r = __connection_second_alloc(co);
|
|
|
|
|
if(r != SNE_SUCCESS) goto __fail3;
|
|
|
|
|
|
|
|
|
|
/* and now we're need to create a thread poll */
|
|
|
|
|
if(!(bundle = malloc(sizeof(sntllv2_bundle_t)))) { r = SNE_ENOMEM; goto __fail4; }
|
|
|
|
|
else {
|
|
|
|
|
bundle->buf = buf;
|
|
|
|
|
bundle->conn = co;
|
|
|
|
|
}
|
|
|
|
|
for(i = 0; i < 8; i++) {
|
|
|
|
|
if(bundle == 0xdead) bundle = __sntll_bundle_create(co);
|
|
|
|
|
if(!bundle) goto __fail5;
|
|
|
|
|
r = pthread_create(&thrd_poll[i], NULL, __sntll_thread, bundle);
|
|
|
|
|
if(r) goto __fail5;
|
|
|
|
|
else bundle = 0xdead;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* all is done, connection now ready */
|
|
|
|
|
co->flags |= SNSX_ALIVE;
|
|
|
|
|
|
|
|
|
|
return co;
|
|
|
|
|
|
|
|
|
|
__fail2:
|
|
|
|
|
if(buf != MAP_FAILED) munmap(buf, 65536);
|
|
|
|
|
SSL_shutdown(co->ssl);
|
|
|
|
|
close(sck);
|
|
|
|
|
__fail:
|
|
|
|
|
if(co) {
|
|
|
|
|
if(co->ssl) SSL_free(co->ssl);
|
|
|
|
|
if(co->ctx) SSL_CTX_free(co->ctx);
|
|
|
|
|
__connection_minimal_free(co);
|
|
|
|
|
}
|
|
|
|
|
errno = r;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|