/* void show(const char *desc, stralloc *s) { buffer_puts(buffer_2,desc); buffer_puthex(buffer_2,s->s,s->len); buffer_putsflush(buffer_2,"\n"); } */ int main(int argc, char * argv[]) { int r; const char* pk0; const char* sk0; /* Check args */ pk0 = ((argc<2) ? env_get("NACL_PUBLICKEY_FILE") : argv[1]); sk0 = ((argc<3) ? env_get("NACL_SECRETKEY_FILE") : argv[2]); if(pk0==0 || sk0==0) strerr_die1x(100,"crypto-box: usage: crypto-box [ publickeyfile ] [ secretkeyfile ]"); /* Read public key */ if(openreadclose(argv[1],&pk,crypto_box_PUBLICKEYBYTES)<=0) strerr_die2sys(111,FATAL,"unable to read public key: "); /* Read secret key */ if(openreadclose(argv[2],&sk,crypto_box_SECRETKEYBYTES)<=0) strerr_die2sys(111,FATAL,"unable to read secret key: "); /* Create shared key */ if(crypto_str_box_beforenm(&k,&pk,&sk)) strerr_die2x(111,FATAL,"failed to create shared-key"); /* Decrypt each chunk */ for (;;) { /* Read nonce */ if((r=netstring_read(buffer_0,&n))!=0) strerr_die2x(111,FATAL,"failed to read nonce"); if(n.len==0) break; if(n.len!=crypto_box_NONCEBYTES) strerr_die2x(111,FATAL,"nonce was incorrect size"); /* Read cipher */ if(netstring_read(buffer_0,&c)!=0) strerr_die2x(111,FATAL,"failed to read cipher"); /* Decrypt message */ if(crypto_str_box_open_afternm(&m,&c,&n,&k)!=0) strerr_die2x(111,FATAL,"decryption failed"); /* Write message */ if(buffer_put(buffer_1,m.s,m.len)!=0) strerr_die2sys(111,FATAL,"failed to output message: "); } buffer_flush(buffer_1); return 0; }
void UnixStreamSocket::userOnUnixStreamRead() { MS_TRACE_STD(); // Be ready to parse more than a single message in a single TCP chunk. while (true) { if (IsClosing()) return; size_t read_len = this->bufferDataLen - this->msgStart; char* json_start = nullptr; size_t json_len; int ns_ret = netstring_read((char*)(this->buffer + this->msgStart), read_len, &json_start, &json_len); if (ns_ret != 0) { switch (ns_ret) { case NETSTRING_ERROR_TOO_SHORT: // MS_DEBUG_STD("received netstring is too short, need more data"); // Check if the buffer is full. if (this->bufferDataLen == this->bufferSize) { // First case: the incomplete message does not begin at position 0 of // the buffer, so move the incomplete message to the position 0. if (this->msgStart != 0) { // MS_DEBUG_STD("no more space in the buffer, moving parsed bytes to the beginning of the buffer and waiting for more data"); std::memmove(this->buffer, this->buffer + this->msgStart, read_len); this->msgStart = 0; this->bufferDataLen = read_len; } // Second case: the incomplete message begins at position 0 of the buffer. // The message is too big, so discard it. else { MS_ERROR_STD("no more space in the buffer for the unfinished message being parsed, discarding it"); this->msgStart = 0; this->bufferDataLen = 0; } } // Otherwise the buffer is not full, just wait. // Exit the parsing loop. return; case NETSTRING_ERROR_TOO_LONG: MS_ERROR_STD("NETSTRING_ERROR_TOO_LONG"); break; case NETSTRING_ERROR_NO_COLON: MS_ERROR_STD("NETSTRING_ERROR_NO_COLON"); break; case NETSTRING_ERROR_NO_COMMA: MS_ERROR_STD("NETSTRING_ERROR_NO_COMMA"); break; case NETSTRING_ERROR_LEADING_ZERO: MS_ERROR_STD("NETSTRING_ERROR_LEADING_ZERO"); break; case NETSTRING_ERROR_NO_LENGTH: MS_ERROR_STD("NETSTRING_ERROR_NO_LENGTH"); break; } // Error, so reset and exit the parsing loop. this->msgStart = 0; this->bufferDataLen = 0; return; } // If here it means that json_start points to the beginning of a JSON string // with json_len bytes length, so recalculate read_len. read_len = (const uint8_t*)json_start - (this->buffer + this->msgStart) + json_len + 1; Json::Value json; std::string json_parse_error; if (this->jsonReader->parse((const char*)json_start, (const char*)json_start + json_len, &json, &json_parse_error)) { Channel::Request* request = nullptr; try { request = new Channel::Request(this, json); } catch (const MediaSoupError &error) { MS_ERROR_STD("discarding wrong Channel request"); } if (request) { // Notify the listener. this->listener->onChannelRequest(this, request); // Delete the Request. delete request; } } else { MS_ERROR_STD("JSON parsing error: %s", json_parse_error.c_str()); } // If there is no more space available in the buffer and that is because // the latest parsed message filled it, then empty the full buffer. if ((this->msgStart + read_len) == this->bufferSize) { // MS_DEBUG_STD("no more space in the buffer, emptying the buffer data"); this->msgStart = 0; this->bufferDataLen = 0; } // If there is still space in the buffer, set the beginning of the next // parsing to the next position after the parsed message. else { this->msgStart += read_len; } // If there is more data in the buffer after the parsed message // then parse again. Otherwise break here and wait for more data. if (this->bufferDataLen > this->msgStart) { // MS_DEBUG_STD("there is more data after the parsed message, continue parsing"); continue; } else { break; } } }
void test_netstring_read(void) { char *netstring; size_t netstring_len; int retval; /* ex1: hello world */ retval = netstring_read(ex1, strlen(ex1), &netstring, &netstring_len); assert(netstring_len == 12); assert(strncmp(netstring, "hello world!", 12) == 0); assert(retval == 0); /* ex2: three netstrings, concatenated. */ retval = netstring_read(ex2, strlen(ex2), &netstring, &netstring_len); assert(netstring_len == 3); assert(strncmp(netstring, "foo", 3) == 0); assert(retval == 0); retval = netstring_read(netstring+netstring_len+1, 9, &netstring, &netstring_len); assert(netstring_len == 0); assert(retval == 0); retval = netstring_read(netstring+netstring_len+1, 6, &netstring, &netstring_len); assert(netstring_len == 3); assert(strncmp(netstring, "bar", 3) == 0); assert(retval == 0); /* ex3: no comma */ retval = netstring_read(ex3, strlen(ex3), &netstring, &netstring_len); assert(netstring_len == 0); assert(netstring == NULL); assert(retval == NETSTRING_ERROR_NO_COMMA); /* ex4: too short */ retval = netstring_read(ex4, strlen(ex4), &netstring, &netstring_len); assert(netstring_len == 0); assert(netstring == NULL); assert(retval == NETSTRING_ERROR_TOO_SHORT); /* ex5: leading zero */ retval = netstring_read(ex5, strlen(ex5), &netstring, &netstring_len); assert(netstring_len == 0); assert(netstring == NULL); assert(retval == NETSTRING_ERROR_LEADING_ZERO); /* ex6: too long */ retval = netstring_read(ex6, strlen(ex6), &netstring, &netstring_len); assert(netstring_len == 0); assert(netstring == NULL); assert(retval == NETSTRING_ERROR_TOO_LONG); /* ex7: no colon */ retval = netstring_read(ex7, strlen(ex7), &netstring, &netstring_len); assert(netstring_len == 0); assert(netstring == NULL); assert(retval == NETSTRING_ERROR_NO_COLON); /* ex8: no number or colon */ retval = netstring_read(ex8, strlen(ex8), &netstring, &netstring_len); assert(netstring_len == 0); assert(netstring == NULL); assert(retval == NETSTRING_ERROR_NO_LENGTH); /* ex9: no number */ retval = netstring_read(ex9, strlen(ex9), &netstring, &netstring_len); assert(netstring_len == 0); assert(netstring == NULL); assert(retval == NETSTRING_ERROR_NO_LENGTH); }