Beispiel #1
0
/**
 * Writes the received payload into payload argument and returns the tag of the message
 */
unsigned char server(unsigned char * payload)
{
    ulong msg_len = PAYLOAD_LEN + 1;
    unsigned char* msg = malloc(msg_len);

    // receive the message
    BIO * b = socket_listen();
    recv(b, msg, msg_len);
    // wait for the client to close, to avoid "Address already in use" errors
    wait_close(b);

    unsigned char * pad = otp(msg_len);         // apply the one-time pad
    xor(msg, pad, msg_len);

    // get the payload
    memcpy(payload, msg + 1, PAYLOAD_LEN);

    // return the tag
    return *msg;
}
Beispiel #2
0
void cmd_pipe_cb(int fd, short event, void *arg)
{
	struct jsonrpc_pipe_cmd *cmd;

	if (read(fd, &cmd, sizeof(cmd)) != sizeof(cmd)) {
		ERR("FATAL ERROR: failed to read from command pipe: %s\n",
				strerror(errno));
		return;
	}


	switch(cmd->type) {
	case CMD_CLOSE:
		if(cmd->server) {
			wait_close(cmd->server);
		}
		goto end;
		break;
	case CMD_RECONNECT:
		if(cmd->server) {
			wait_reconnect(cmd->server);
		}
		goto end;
		break;
	case CMD_CONNECT:
		if(cmd->server) {
			bev_connect(cmd->server);
		}
		goto end;
		break;
	case CMD_UPDATE_SERVER_GROUP:
		if(cmd->new_grp) {
			jsonrpc_server_group_t* old_grp = *global_server_group;
			*global_server_group = cmd->new_grp;
			free_server_group(&old_grp);
		}
		lock_release(jsonrpc_server_group_lock);
		goto end;
		break;

	case CMD_SEND:
		break;

	default:
		ERR("Unrecognized pipe command: %d\n", cmd->type);
		goto end;
		break;
	}

	/* command is SEND */

	jsonrpc_req_cmd_t* req_cmd = cmd->req_cmd;
	if(req_cmd == NULL) {
		ERR("req_cmd is NULL. Invalid send command\n");
		goto end;
	}

	jsonrpc_request_t* req = NULL;
	req = create_request(req_cmd);
	if (!req || !req->payload) {
		json_t* error = internal_error(JRPC_ERR_REQ_BUILD, NULL);
		pv_value_t val;
		char* freeme = NULL;
		jsontoval(&val, &freeme, error);
		if(req_cmd->route.len <=0 && send_to_script(&val, req_cmd)<0) {
			ERR("Failed to build request (method: %.*s, params: %.*s)\n",
					STR(req_cmd->method), STR(req_cmd->params));
		}
		if(freeme) free(freeme);
		if(error) json_decref(error);
		free_req_cmd(req_cmd);
		goto end;
	}

	int sent = jsonrpc_send(req_cmd->conn, req, req_cmd->notify_only);

	char* type;
	if (sent<0) {
		if (req_cmd->notify_only == false) {
			type = "Request";
		} else {
			type = "Notification";
		}
		WARN("%s could not be sent to connection group: %.*s\n",
				type, STR(req_cmd->conn));
		fail_request(JRPC_ERR_SEND, req, "Failed to send request");
	}

end:
	free_pipe_cmd(cmd);
}
Beispiel #3
0
int main(int argc, char ** argv)
{
  // our identity and the identity of the other partner
  unsigned char * host, * xhost;
  size_t host_len, xhost_len;

  unsigned char * pkey, * skey, * xkey;
  size_t pkey_len, skey_len, xkey_len;

  unsigned char * m1, * m1_e;
  unsigned char * xNa, * xNb;
  size_t m1_len, m1_e_len;
  size_t m1_l;

  unsigned char * m2, * m2_e;
  unsigned char * Nb;
  size_t m2_len, m2_e_len;

  unsigned char * m3, * m3_e;
  size_t m3_len, m3_e_len;

  unsigned char * p;

  // for dropping encryption tags
  unsigned char * dummy = malloc(4);

  BIO * bio = socket_listen();

  host = get_host(&host_len, 'B');

  pkey = get_pkey(&pkey_len, 'B');
  skey = get_skey(&skey_len, 'B');

#ifdef VERBOSE
  printf("B pkey = ");
  print_buffer(pkey, pkey_len);
  printf("\n");

  printf("B skey = ");
  print_buffer(skey, skey_len);
  printf("\n");
#endif


  /* Receive message 1 */

  recv(bio, (unsigned char*) &m1_e_len, sizeof(m1_e_len));

  if(m1_e_len > MAX_SIZE_CIPHER)
    fail("Server: cipher in message 1 too long");

  m1_e = malloc(m1_e_len);
  recv(bio, m1_e, m1_e_len);

  m1_len = decrypt_len(skey, skey_len, m1_e, m1_e_len);
  m1 = malloc(m1_len);
  m1_len = decrypt(skey, skey_len, m1_e, m1_e_len, m1);

  if(sizeof(size_t) + SIZE_NONCE + 4 > m1_len)
  {
    fprintf(stderr, "m1 has wrong length\n");
    exit(1);
  }

  if(memcmp(m1, "msg1", 4))
  {
    fprintf(stderr, "B: m1 not properly tagged, aborting\n");
    exit(1);
  }

  m1_l = * (size_t *) (m1 + 4);

  if(m1_l !=  SIZE_NONCE)
  {
    fprintf(stderr, "A: m1 contains wrong length for xNa\n");
    exit(1);
  }

  xhost_len = m1_len - (4 + sizeof(size_t) + m1_l);
  xhost = m1 + 4 + sizeof(size_t) + m1_l;

  if(xhost_len > MAX_SIZE_HOST)
    fail("B: host size in m1 too long");

#ifdef VERBOSE
  printf("B xhost = ");
  print_buffer(xhost, xhost_len);
  printf("\n");
#endif

  xkey = lookup_xkey(&xkey_len, xhost, xhost_len, 'B');

#ifdef VERBOSE
  printf("B xkey = ");
  print_buffer(xkey, xkey_len);
  printf("\n");
#endif

  /*
  if(memcmp(m1 + sizeof(size_t) + m1_l + 4, xkey,  xkey_len))
  {
    fprintf(stderr, "x_xkey in m1 doesn't match xkey\n");
    exit(1);
  }
  */

  xNa = m1 + 4 + sizeof(size_t);
  typehint(xNa, m1_l, "fixed_20_nonce");

#ifdef VERBOSE
    fprintf(stderr, "B: m1 received and checked");
    fprintf(stderr, "\n");
    fflush(stderr);
#endif

#ifdef CSEC_VERIFY
#ifdef USE_EVENT_PARAMS
  event2("server_begin", xhost, xhost_len, host, host_len);
#else
  event0("server_begin");
#endif
#endif

  /* Send message 2 */

  m2_len = 2 * SIZE_NONCE + 2 * sizeof(size_t) + 4 + host_len;
  p = m2 = malloc(m2_len);

  memcpy(p, "msg2", 4);
  p += 4;
  * (size_t *) p = m1_l;
  p += sizeof(size_t);
  * (size_t *) p = SIZE_NONCE;
  p += sizeof(size_t);
  memcpy(p, xNa, m1_l);
  p += m1_l;
  Nb = p;
  nonce(Nb);
  p += SIZE_NONCE;
  memcpy(p, host, host_len);

  m2_e_len = encrypt_len(xkey, xkey_len, m2, m2_len);

  if(m2_e_len > MAX_SIZE_CIPHER)
    fail("Server: cipher in message 2 too long");

  m2_e = malloc(m2_e_len);
  m2_e_len = encrypt(xkey, xkey_len, m2, m2_len, m2_e);

  send(bio, &m2_e_len, sizeof(m2_e_len));
  send(bio, m2_e, m2_e_len);

#ifdef VERBOSE
  printf("B: m2_e sent, m2_e = ");
  print_buffer(m2_e, m2_e_len);
  printf("\n");
  fflush(stdout);
#endif

  /* Receive message 3 */

  recv(bio, (unsigned char*) &m3_e_len, sizeof(m3_e_len));

  if(m3_e_len > MAX_SIZE_CIPHER)
    fail("Server: cipher in message 3 too long");

  m3_e = malloc(m3_e_len);
  recv(bio, m3_e, m3_e_len);

  m3_len = decrypt_len(skey, skey_len, m3_e, m3_e_len);
  m3 = malloc(m3_len);
  m3_len = decrypt(skey, skey_len, m3_e, m3_e_len, m3);

  if(memcmp(m3, "msg3", 4))
  {
    fprintf(stderr, "B: m3 not properly tagged, aborting\n");
    exit(1);
  }

  if(m3_len != SIZE_NONCE + 4)
  {
    fprintf(stderr, "B: m3 has wrong length\n");
    exit(1);
  }

  xNb = m3 + 4;
  typehint(xNb, SIZE_NONCE, "fixed_20_nonce");

  if(memcmp(xNb, Nb, SIZE_NONCE))
  {
    fprintf(stderr, "xNb in m3 doesn't match Nb\n");
    exit(1);
  }

#ifdef VERBOSE
    printf("B: Na = ");
    print_buffer(xNa, SIZE_NONCE);
    printf("\n");
    printf("B: Nb = ");
    print_buffer(Nb, SIZE_NONCE);
    printf("\n");
    fflush(stdout);
#endif

#ifdef CSEC_VERIFY
#ifdef USE_EVENT_PARAMS
  event2("server_end", xhost, xhost_len, host, host_len);
#else
  event0("server_end");
#endif
#endif

  // wait for the client to close, to avoid "Address already in use" errors
  wait_close(bio);

  return 0;
}