Ejemplo n.º 1
0
Archivo: ps.c Proyecto: anlaneg/openvpn
/*
 * Create a new pair of proxy_connection entries, one for each
 * socket file descriptor involved in the proxy.  We are given
 * the client fd, and we should derive our own server fd by connecting
 * to the server given by server_addr/server_port.  Return true
 * on success and false on failure to connect to server.
 */
static bool
proxy_entry_new(struct proxy_connection **list,
                struct event_set *es,
                const struct sockaddr_in server_addr,
                const socket_descriptor_t sd_client,
                struct buffer *initial_data,
                const char *journal_dir)
{
    socket_descriptor_t sd_server;
    int status;
    struct proxy_connection *pc;
    struct proxy_connection *cp;

    /* connect to port share server */
    if ((sd_server = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
    {
        msg(M_WARN|M_ERRNO, "PORT SHARE PROXY: cannot create socket");
        return false;
    }
    status = openvpn_connect(sd_server,(const struct sockaddr *)  &server_addr, 5, NULL);
    if (status)
    {
        msg(M_WARN, "PORT SHARE PROXY: connect to port-share server failed");
        openvpn_close_socket(sd_server);
        return false;
    }
    dmsg(D_PS_PROXY_DEBUG, "PORT SHARE PROXY: connect to port-share server succeeded");

    set_nonblock(sd_client);
    set_nonblock(sd_server);

    /* allocate 2 new proxy_connection objects */
    ALLOC_OBJ_CLEAR(pc, struct proxy_connection);
    ALLOC_OBJ_CLEAR(cp, struct proxy_connection);

    /* client object */
    pc->defined = true;
    pc->next = cp;
    pc->counterpart = cp;
    pc->buf = *initial_data;
    pc->buffer_initial = true;
    pc->rwflags = EVENT_UNDEF;
    pc->sd = sd_client;

    /* server object */
    cp->defined = true;
    cp->next = *list;
    cp->counterpart = pc;
    cp->buf = alloc_buf(PROXY_CONNECTION_BUFFER_SIZE);
    cp->buffer_initial = false;
    cp->rwflags = EVENT_UNDEF;
    cp->sd = sd_server;

    /* add to list */
    *list = pc;

    /* add journal entry */
    if (journal_dir)
    {
        journal_add(journal_dir, pc, cp);
    }

    dmsg(D_PS_PROXY_DEBUG, "PORT SHARE PROXY: NEW CONNECTION [c=%d s=%d]", (int)sd_client, (int)sd_server);

    /* set initial i/o states */
    proxy_connection_io_requeue(pc, EVENT_READ, es);
    proxy_connection_io_requeue(cp, EVENT_READ|EVENT_WRITE, es);

    return true;
}
Ejemplo n.º 2
0
	int bof(buffer * str) {
	buffer * dst = alloc_buf((24));
	str_copy(dst, str);
	return 1;
	
	}
Ejemplo n.º 3
0
static char *
common_flags_to_string (FlagType flags,
			int object_type,
			FlagBitsType *flagbits,
			int n_flagbits)
{
  int len;
  int i;
  FlagHolder fh, savef;
  char *buf, *bp;
  unknown_flag_t *u;

  fh.Flags = flags;

#ifndef FLAG_TEST
  switch (object_type)
    {
    case VIA_TYPE:
      CLEAR_FLAG (VIAFLAG, &fh);
      break;
    case RATLINE_TYPE:
      CLEAR_FLAG (RATFLAG, &fh);
      break;
    case PIN_TYPE:
      CLEAR_FLAG (PINFLAG, &fh);
      break;
    }
#endif

  savef = fh;

  len = 3;			/* for "()\0" */

  for (i = 0; i < n_flagbits; i++)

    if ((flagbits[i].object_types & object_type)
	&& (TEST_FLAG (flagbits[i].mask, &fh)))
      {

	len += flagbits[i].nlen + 1;
	CLEAR_FLAG (flagbits[i].mask, &fh);
      }

  if (TEST_ANY_THERMS (&fh))
    {
      len += sizeof ("thermal()");
      for (i = 0; i < MAX_LAYER; i++)
	if (TEST_THERM (i, &fh))
	  len += printed_int_length (i, GET_THERM (i, &fh)) + 1;
    }

  if (flags.q > 0)
    {
      len += sizeof ("shape(.)");
			if (flags.q > 9)
				len+=2;
    }

  if (flags.int_conn_grp > 0)
    {
      len += sizeof ("intconn(.)");
			if (flags.q > 9)
				len++;
			if (flags.q > 99)
				len++;
    }

	for(u = flags.unknowns; u != NULL; u = u->next)
		len += strlen(u->str)+1;

  bp = buf = alloc_buf (len + 2);

  *bp++ = '"';

  fh = savef;
  for (i = 0; i < n_flagbits; i++)
    if (flagbits[i].object_types & object_type
	&& (TEST_FLAG (flagbits[i].mask, &fh)))
      {
	if (bp != buf + 1)
	  *bp++ = ',';
	strcpy (bp, flagbits[i].name);
	bp += flagbits[i].nlen;
	CLEAR_FLAG (flagbits[i].mask, &fh);
      }

  if (TEST_ANY_THERMS (&fh))
    {
      if (bp != buf + 1)
	*bp++ = ',';
      strcpy (bp, "thermal");
      bp += strlen ("thermal");
      grow_layer_list (0);
      for (i = 0; i < MAX_LAYER; i++)
	if (TEST_THERM (i, &fh))
	  set_layer_list (i, GET_THERM (i, &fh));
      strcpy (bp, print_layer_list ());
      bp += strlen (bp);
    }

  if (flags.q > 0)
    {
			if (bp != buf + 1)
				*bp++ = ',';
			bp += sprintf(bp, "shape(%d)", flags.q);
    }

  if (flags.int_conn_grp > 0)
    {
			if (bp != buf + 1)
				*bp++ = ',';
			bp += sprintf(bp, "intconn(%d)", flags.int_conn_grp);
    }

	for(u = flags.unknowns; u != NULL; u = u->next) {
		int len;
		len = strlen(u->str);
		if (bp != buf + 1)
			*bp++ = ',';
		memcpy(bp, u->str, len);
		bp += len;
	}

  *bp++ = '"';
  *bp = 0;
  return buf;
}
Ejemplo n.º 4
0
/*
 * This function runs in the context of the background proxy process.
 * Receive a control message from the parent (sent by the port_share_sendmsg
 * function above) and act on it.  Return false if the proxy process should
 * exit, true otherwise.
 */
static bool
control_message_from_parent (const socket_descriptor_t sd_control,
			     struct proxy_connection **list,
			     struct event_set *es,
			     const struct sockaddr_in server_addr,
			     const int max_initial_buf,
			     const char *journal_dir)
{
  /* this buffer needs to be large enough to handle the largest buffer
     that might be returned by the link_socket_read call in read_incoming_link. */
  struct buffer buf = alloc_buf (max_initial_buf);

  struct msghdr mesg;
  struct cmsghdr* h;
  struct iovec iov[2];
  char command = 0;
  ssize_t status;
  int ret = true;

  CLEAR (mesg);

  iov[0].iov_base = &command;
  iov[0].iov_len = sizeof (command);
  iov[1].iov_base = BPTR (&buf);
  iov[1].iov_len = BCAP (&buf);
  mesg.msg_iov = iov;
  mesg.msg_iovlen = 2;

  mesg.msg_controllen = cmsg_size ();
  mesg.msg_control = (char *) malloc (mesg.msg_controllen);
  check_malloc_return (mesg.msg_control);
  mesg.msg_flags = 0;

  h = CMSG_FIRSTHDR(&mesg);
  h->cmsg_len = CMSG_LEN(sizeof(socket_descriptor_t));
  h->cmsg_level = SOL_SOCKET;
  h->cmsg_type = SCM_RIGHTS;
  *((socket_descriptor_t*)CMSG_DATA(h)) = SOCKET_UNDEFINED;

  status = recvmsg (sd_control, &mesg, MSG_NOSIGNAL);
  if (status != -1)
    {
      if (   h == NULL
	  || h->cmsg_len    != CMSG_LEN(sizeof(socket_descriptor_t))
	  || h->cmsg_level  != SOL_SOCKET
	  || h->cmsg_type   != SCM_RIGHTS )
	{
	  msg (M_WARN, "PORT SHARE PROXY: received unknown message");
	}
      else
	{
	  const socket_descriptor_t received_fd = *((socket_descriptor_t*)CMSG_DATA(h));
	  dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: RECEIVED sd=%d", (int)received_fd);

	  if (status >= 2 && command == COMMAND_REDIRECT)
	    {
	      buf.len = status - 1;
	      if (proxy_entry_new (list,
				   es,
				   server_addr,
				   received_fd,
				   &buf,
				   journal_dir))
		{
		  CLEAR (buf); /* we gave the buffer to proxy_entry_new */
		}
	      else
		{
		  openvpn_close_socket (received_fd);
		}
	    }
	  else if (status >= 1 && command == COMMAND_EXIT)
	    {
	      dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: RECEIVED COMMAND_EXIT");
	      openvpn_close_socket (received_fd); /* null socket */
	      ret = false;
	    }
	}
    }
  free (mesg.msg_control);
  free_buf (&buf);
  return ret;
}
Ejemplo n.º 5
0
static FlagType
common_string_to_flags (const char *flagstring,
			int (*error) (const char *msg),
			FlagBitsType *flagbits,
			int n_flagbits)
{
  const char *fp, *ep;
  int flen;
  FlagHolder rv;
  int i;

  rv.Flags = empty_flags;

  if (error == 0)
    error = error_ignore;

  if (flagstring == NULL)
    return empty_flags;

  fp = ep = flagstring;

  if (*fp == '"')
    ep = ++fp;

  while (*ep && *ep != '"')
    {
      int found = 0;

      for (ep = fp; *ep && *ep != ',' && *ep != '"' && *ep != '('; ep++)
	;
      flen = ep - fp;
      if (*ep == '(')
	ep = parse_layer_list (ep + 1, error);

      if (flen == 7 && memcmp (fp, "thermal", 7) == 0)
	{
	  for (i = 0; i < MAX_LAYER && i < num_layers; i++)
	    if (layers[i])
	      ASSIGN_THERM (i, layers[i], &rv);
	}
      else
      if (flen == 5 && memcmp (fp, "shape", 5) == 0)
	{
		rv.Flags.q=atoi(fp+6);
	}
      else
      if (flen == 7 && memcmp (fp, "intconn", 7) == 0)
	{
		rv.Flags.int_conn_grp=atoi(fp+8);
	}
      else
	{
	  for (i = 0; i < n_flagbits; i++)
	    if (flagbits[i].nlen == flen
		&& memcmp (flagbits[i].name, fp, flen) == 0)
	      {
		found = 1;
		SET_FLAG (flagbits[i].mask, &rv);
		break;
	      }
	  if (!found)
	    {
	      const char *fmt = "Unknown flag: \"%.*s\" ignored";
	      unknown_flag_t *u;
	      char *msg, *s;

	      /* include () */
	      s = fp + flen;
	      if (*s == '(') {
	      	while(*s != ')') {
	      		flen++;
	      		s++;
	      	}
	      }
	      if (*s == ')')
	      	flen++;

	      msg = alloc_buf (strlen (fmt) + flen);
	      sprintf (msg, fmt, flen, fp);
	      error (msg);

	      u = malloc(sizeof(unknown_flag_t));
	      u->str = strndup(fp, flen);
	      u->next = NULL;
	      /* need to append, to keep order of flags */
	      if (rv.Flags.unknowns != NULL) {
	      	unknown_flag_t *n;
	      	for(n = rv.Flags.unknowns; n->next != NULL; n = n->next) ;
	      	n->next = u;
	      }
	      else
	      	rv.Flags.unknowns = u;
	    }
	}
      fp = ep + 1;
    }
  return rv.Flags;
}