Esempio n. 1
0
gc_malloc (size_t size, bool clear, struct gc_arena *a)
#endif
{
  void *ret;
  if (a)
    {
      struct gc_entry *e;
#ifdef DMALLOC
      e = (struct gc_entry *) openvpn_dmalloc (file, line, size + sizeof (struct gc_entry));
#else
      e = (struct gc_entry *) malloc (size + sizeof (struct gc_entry));
#endif
      check_malloc_return (e);
      ret = (char *) e + sizeof (struct gc_entry);
      e->next = a->list;
      a->list = e;
    }
  else
    {
#ifdef DMALLOC
      ret = openvpn_dmalloc (file, line, size);
#else
      ret = malloc (size);
#endif
      check_malloc_return (ret);
    }
#ifndef ZERO_BUFFER_ON_ALLOC
  if (clear)
#endif
    memset (ret, 0, size);
  return ret;
}
Esempio n. 2
0
static char *
env_block (const struct env_set *es)
{
  if (es)
    {
      struct env_item *e;
      char *ret;
      char *p;
      size_t nchars = 1;
      
      for (e = es->list; e != NULL; e = e->next)
	nchars += strlen (e->string) + 1;

      ret = (char *) malloc (nchars);
      check_malloc_return (ret);

      p = ret;
      for (e = es->list; e != NULL; e = e->next)
	{
	  if (env_allowed (e->string))
	    {
	      strcpy (p, e->string);
	      p += strlen (e->string) + 1;
	    }
	}
      *p = '\0';
      return ret;
    }
  else
    return NULL;
}
Esempio n. 3
0
static char *
env_block(const struct env_set *es)
{
    char force_path[256];
    char *sysroot = get_win_sys_path();

    if (!openvpn_snprintf(force_path, sizeof(force_path), "PATH=%s\\System32;%s;%s\\System32\\Wbem",
                          sysroot, sysroot, sysroot))
    {
        msg(M_WARN, "env_block: default path truncated to %s", force_path);
    }

    if (es)
    {
        struct env_item *e;
        char *ret;
        char *p;
        size_t nchars = 1;
        bool path_seen = false;

        for (e = es->list; e != NULL; e = e->next)
        {
            nchars += strlen(e->string) + 1;
        }

        nchars += strlen(force_path)+1;

        ret = (char *) malloc(nchars);
        check_malloc_return(ret);

        p = ret;
        for (e = es->list; e != NULL; e = e->next)
        {
            if (env_allowed(e->string))
            {
                strcpy(p, e->string);
                p += strlen(e->string) + 1;
            }
            if (strncmp(e->string, "PATH=", 5 ) == 0)
            {
                path_seen = true;
            }
        }

        /* make sure PATH is set */
        if (!path_seen)
        {
            msg( M_INFO, "env_block: add %s", force_path );
            strcpy( p, force_path );
            p += strlen(force_path) + 1;
        }

        *p = '\0';
        return ret;
    }
    else
    {
        return NULL;
    }
}
Esempio n. 4
0
static void
argv_system_str_append (struct argv *a, const char *str, const bool enquote)
{
  if (str)
    {
      char *newstr;

      /* compute length of new system_str */
      size_t l = strlen (str) + 1; /* space for new string plus trailing '\0' */
      if (a->system_str)
	l += strlen (a->system_str) + 1; /* space for existing string + space (" ") separator */
      if (enquote)
	l += 2; /* space for two quotes */

      /* build new system_str */
      newstr = (char *) malloc (l);
      newstr[0] = '\0';
      check_malloc_return (newstr);
      if (a->system_str)
	{
	  strcpy (newstr, a->system_str);
	  strcat (newstr, " ");
	}
      if (enquote)
	strcat (newstr, "\"");
      strcat (newstr, str);
      if (enquote)
	strcat (newstr, "\"");
      free (a->system_str);
      a->system_str = newstr;
    }
}
Esempio n. 5
0
HMAC_CTX *
hmac_ctx_new(void)
{
    HMAC_CTX *ctx = HMAC_CTX_new();
    check_malloc_return(ctx);
    return ctx;
}
Esempio n. 6
0
cipher_ctx_t *
cipher_ctx_new(void)
{
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    check_malloc_return(ctx);
    return ctx;
}
Esempio n. 7
0
static bool
pkcs11_get_x509_cert(pkcs11h_certificate_t pkcs11_cert, mbedtls_x509_crt *cert)
{
    unsigned char *cert_blob = NULL;
    size_t cert_blob_size = 0;
    bool ret = false;

    if (pkcs11h_certificate_getCertificateBlob(pkcs11_cert, NULL,
                                               &cert_blob_size) != CKR_OK)
    {
        msg(M_WARN, "PKCS#11: Cannot retrieve certificate object size");
        goto cleanup;
    }

    check_malloc_return((cert_blob = calloc(1, cert_blob_size)));
    if (pkcs11h_certificate_getCertificateBlob(pkcs11_cert, cert_blob,
                                               &cert_blob_size) != CKR_OK)
    {
        msg(M_WARN, "PKCS#11: Cannot retrieve certificate object");
        goto cleanup;
    }

    if (!mbed_ok(mbedtls_x509_crt_parse(cert, cert_blob, cert_blob_size)))
    {
        msg(M_WARN, "PKCS#11: Could not parse certificate");
        goto cleanup;
    }

    ret = true;
cleanup:
    free(cert_blob);
    return ret;
}
Esempio n. 8
0
string_alloc (const char *str, struct gc_arena *gc)
#endif
{
  if (str)
    {
      const int n = strlen (str) + 1;
      char *ret;

      if (gc) {
#ifdef DMALLOC
        ret = (char *) gc_malloc_debug (n, false, gc, file, line);
#else
        ret = (char *) gc_malloc (n, false, gc);
#endif
      } else {
        /* If there are no garbage collector available, it's expected
         * that the caller cleans up afterwards.  This is coherent with the
         * earlier behaviour when gc_malloc() would be called with gc == NULL
         */
#ifdef DMALLOC
        ret = openvpn_dmalloc (file, line, n);
        memset(ret, 0, n);
#else
        ret = calloc(1, n);
#endif
        check_malloc_return(ret);
      }
      memcpy (ret, str, n);
      return ret;
    }
  else
    return NULL;
}
Esempio n. 9
0
EVP_MD_CTX *
md_ctx_new(void)
{
    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
    check_malloc_return(ctx);
    return ctx;
}
Esempio n. 10
0
static WCHAR *
wide_cmd_line(const struct argv *a, struct gc_arena *gc)
{
    size_t nchars = 1;
    size_t maxlen = 0;
    size_t i;
    struct buffer buf;
    char *work = NULL;

    if (!a)
    {
        return NULL;
    }

    for (i = 0; i < a->argc; ++i)
    {
        const char *arg = a->argv[i];
        const size_t len = strlen(arg);
        nchars += len + 3;
        if (len > maxlen)
        {
            maxlen = len;
        }
    }

    work = gc_malloc(maxlen + 1, false, gc);
    check_malloc_return(work);
    buf = alloc_buf_gc(nchars, gc);

    for (i = 0; i < a->argc; ++i)
    {
        const char *arg = a->argv[i];
        strcpy(work, arg);
        string_mod(work, CC_PRINT, CC_DOUBLE_QUOTE|CC_CRLF, '_');
        if (i)
        {
            buf_printf(&buf, " ");
        }
        if (string_class(work, CC_ANY, CC_SPACE))
        {
            buf_printf(&buf, "%s", work);
        }
        else
        {
            buf_printf(&buf, "\"%s\"", work);
        }
    }

    return wide_string(BSTR(&buf), gc);
}
Esempio n. 11
0
static void
lzo_compress_init(struct compress_context *compctx)
{
    msg(D_INIT_MEDIUM, "LZO compression initializing");
    ASSERT(!(compctx->flags & COMP_F_SWAP));
    compctx->wu.lzo.wmem_size = LZO_WORKSPACE;

    int lzo_status = lzo_init();
    if (lzo_status != LZO_E_OK)
    {
        msg(M_FATAL, "Cannot initialize LZO compression library (lzo_init() returns %d)", lzo_status);
    }
    compctx->wu.lzo.wmem = (lzo_voidp) lzo_malloc(compctx->wu.lzo.wmem_size);
    check_malloc_return(compctx->wu.lzo.wmem);
}
Esempio n. 12
0
/* worker method for setenv_x509_track */
static void
do_setenv_x509 (struct env_set *es, const char *name, char *value, int depth)
{
  char *name_expand;
  size_t name_expand_size;

  string_mod (value, CC_ANY, CC_CRLF, '?');
  msg (D_X509_ATTR, "X509 ATTRIBUTE name='%s' value='%s' depth=%d", name, value, depth);
  name_expand_size = 64 + strlen (name);
  name_expand = (char *) malloc (name_expand_size);
  check_malloc_return (name_expand);
  openvpn_snprintf (name_expand, name_expand_size, "X509_%d_%s", depth, name);
  setenv_str (es, name_expand, value);
  free (name_expand);
}
Esempio n. 13
0
clone_buf (const struct buffer* buf)
#endif
{
  struct buffer ret;
  ret.capacity = buf->capacity;
  ret.offset = buf->offset;
  ret.len = buf->len;
#ifdef DMALLOC
  ret.data = (uint8_t *) openvpn_dmalloc (file, line, buf->capacity);
#else
  ret.data = (uint8_t *) malloc (buf->capacity);
#endif
  check_malloc_return (ret.data);
  memcpy (BPTR (&ret), BPTR (buf), BLEN (buf));
  return ret;
}
void gc_addspecial (void *addr, void (free_function)(void*), struct gc_arena *a)
{
  ASSERT(a);
  struct gc_entry_special *e;
#ifdef DMALLOC
  e = (struct gc_entry_special *) openvpn_dmalloc (file, line, sizeof (struct gc_entry_special));
#else
  e = (struct gc_entry_special *) malloc (sizeof (struct gc_entry_special));
#endif
  check_malloc_return (e);
  e->free_fnc = free_function;
  e->addr = addr;

  e->next = a->list_special;
  a->list_special = e;
}
Esempio n. 15
0
static char *
env_block (const struct env_set *es)
{
  char * force_path = "PATH=C:\\Windows\\System32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem";

  if (es)
    {
      struct env_item *e;
      char *ret;
      char *p;
      size_t nchars = 1;
      bool path_seen = false;
      
      for (e = es->list; e != NULL; e = e->next)
	nchars += strlen (e->string) + 1;

      nchars += strlen(force_path)+1;

      ret = (char *) malloc (nchars);
      check_malloc_return (ret);

      p = ret;
      for (e = es->list; e != NULL; e = e->next)
	{
	  if (env_allowed (e->string))
	    {
	      strcpy (p, e->string);
	      p += strlen (e->string) + 1;
	    }
	  if ( strncmp(e->string, "PATH=", 5 ) == 0 )
	    path_seen = true;
	}

      /* make sure PATH is set */
      if ( !path_seen )
	{
	  msg( M_INFO, "env_block: add %s", force_path );
	  strcpy( p, force_path );
	  p += strlen(force_path) + 1;
	}

      *p = '\0';
      return ret;
    }
  else
    return NULL;
}
Esempio n. 16
0
/*
 * Save X509 fields to environment, using the naming convention:
 *
 *  X509_{cert_depth}_{name}={value}
 */
void
x509_setenv (struct env_set *es, int cert_depth, openvpn_x509_cert_t *peer_cert)
{
  int i, n;
  int fn_nid;
  ASN1_OBJECT *fn;
  ASN1_STRING *val;
  X509_NAME_ENTRY *ent;
  const char *objbuf;
  unsigned char *buf;
  char *name_expand;
  size_t name_expand_size;
  X509_NAME *x509 = X509_get_subject_name (peer_cert);

  n = X509_NAME_entry_count (x509);
  for (i = 0; i < n; ++i)
    {
      ent = X509_NAME_get_entry (x509, i);
      if (!ent)
	continue;
      fn = X509_NAME_ENTRY_get_object (ent);
      if (!fn)
	continue;
      val = X509_NAME_ENTRY_get_data (ent);
      if (!val)
	continue;
      fn_nid = OBJ_obj2nid (fn);
      if (fn_nid == NID_undef)
	continue;
      objbuf = OBJ_nid2sn (fn_nid);
      if (!objbuf)
	continue;
      buf = (unsigned char *)1; /* bug in OpenSSL 0.9.6b ASN1_STRING_to_UTF8 requires this workaround */
      if (ASN1_STRING_to_UTF8 (&buf, val) <= 0)
	continue;
      name_expand_size = 64 + strlen (objbuf);
      name_expand = (char *) malloc (name_expand_size);
      check_malloc_return (name_expand);
      openvpn_snprintf (name_expand, name_expand_size, "X509_%d_%s", cert_depth,
	  objbuf);
      string_mod (name_expand, CC_PRINT, CC_CRLF, '_');
      string_mod ((char*)buf, CC_PRINT, CC_CRLF, '_');
      setenv_str (es, name_expand, (char*)buf);
      free (name_expand);
      OPENSSL_free (buf);
    }
}
Esempio n. 17
0
char *
argv_term (const char **f)
{
  const char *p = *f;
  const char *term = NULL;
  size_t termlen = 0;

  if (*p == '\0')
    return NULL;

  while (true)
    {
      const int c = *p;
      if (c == '\0')
	break;
      if (term)
	{
	  if (!isspace (c))
	    ++termlen;
	  else
	    break;
	}
      else
	{
	  if (!isspace (c))
	    {
	      term = p;
	      termlen = 1;
	    }
	}
      ++p;
    }
  *f = p;

  if (term)
    {
      char *ret;
      ASSERT (termlen > 0);
      ret = malloc (termlen + 1);
      check_malloc_return (ret);
      memcpy (ret, term, termlen);
      ret[termlen] = '\0';
      return ret;
    }
  else
    return NULL;
}
Esempio n. 18
0
/*
 *  This is exactly like clone_buf, but uses malloc to allocate the memory so that it can be cached
 *  properly
 */
struct buffer*
full_clone_buf(const struct buffer* buf)
{
  struct buffer* ret = (struct buffer*) malloc(sizeof(struct buffer));
  ret->capacity = buf->capacity;
  ret->offset = buf->offset;
  ret->len = buf->len;
#ifdef DMALLOC
  ret->data = (uint8_t *) openvpn_dmalloc (file, line, buf->capacity);
#else
  ret->data = (uint8_t *) malloc (buf->capacity);
#endif
  check_malloc_return (ret->data);
  memcpy (BPTR (ret), BPTR (buf), BLEN (buf));
  return ret;
  
}
Esempio n. 19
0
void
prng_init (const char *md_name, const int nonce_secret_len_parm)
{
  prng_uninit ();
  nonce_md = md_name ? md_kt_get (md_name) : NULL;
  if (nonce_md)
    {
      ASSERT (nonce_secret_len_parm >= NONCE_SECRET_LEN_MIN && nonce_secret_len_parm <= NONCE_SECRET_LEN_MAX);
      nonce_secret_len = nonce_secret_len_parm;
      {
	const int size = md_kt_size(nonce_md) + nonce_secret_len;
	dmsg (D_CRYPTO_DEBUG, "PRNG init md=%s size=%d", md_kt_name(nonce_md), size);
	nonce_data = (uint8_t*) malloc (size);
	check_malloc_return (nonce_data);
	prng_reset_nonce();
      }
    }
}
Esempio n. 20
0
alloc_buf (size_t size)
#endif
{
  struct buffer buf;

  if (!buf_size_valid (size))
    buf_size_error (size);
  buf.capacity = (int)size;
  buf.offset = 0;
  buf.len = 0;
#ifdef DMALLOC
  buf.data = openvpn_dmalloc (file, line, size);
#else
  buf.data = calloc (1, size);
#endif
  check_malloc_return(buf.data);

  return buf;
}
void
buffer_list_aggregate_separator (struct buffer_list *bl, const size_t max, const char *sep)
{
  int sep_len = strlen(sep);

  if (bl->head)
    {
      struct buffer_entry *more = bl->head;
      size_t size = 0;
      int count = 0;
      for (count = 0; more && size <= max; ++count)
	{
	  size += BLEN(&more->buf) + sep_len;
	  more = more->next;
	}

      if (count >= 2)
	{
	  int i;
	  struct buffer_entry *e = bl->head, *f;

	  ALLOC_OBJ_CLEAR (f, struct buffer_entry);
	  f->buf.data = malloc (size);
	  check_malloc_return (f->buf.data);
	  f->buf.capacity = size;
	  for (i = 0; e && i < count; ++i)
	    {
	      struct buffer_entry *next = e->next;
	      buf_copy (&f->buf, &e->buf);
	      buf_write(&f->buf, sep, sep_len);
	      free_buf (&e->buf);
	      free (e);
	      e = next;
	    }
	  bl->head = f;
	  f->next = more;
	  if (!more)
	    bl->tail = f;
	}
    }
}
Esempio n. 22
0
static char *
cmd_line (const struct argv *a)
{
  size_t nchars = 1;
  size_t maxlen = 0;
  size_t i;
  struct buffer buf;
  char *work = NULL;

  if (!a)
    return NULL;

  for (i = 0; i < a->argc; ++i)
    {
      const char *arg = a->argv[i];
      const size_t len = strlen (arg);
      nchars += len + 3;
      if (len > maxlen)
	maxlen = len;
    }

  work = (char *) malloc (maxlen + 1);
  check_malloc_return (work);
  buf = alloc_buf (nchars);

  for (i = 0; i < a->argc; ++i)
    {
      const char *arg = a->argv[i];
      strcpy (work, arg);
      string_mod (work, CC_PRINT, CC_DOUBLE_QUOTE|CC_CRLF, '_');
      if (i)
	buf_printf (&buf, " ");
      if (string_class (work, CC_ANY, CC_SPACE))
	buf_printf (&buf, "%s", work);
      else
	buf_printf (&buf, "\"%s\"", work);
    }

  free (work);
  return BSTR(&buf);
}
Esempio n. 23
0
File: ps.c Progetto: OpenVPN/openvpn
/*
 * Record IP/port of client in filesystem, so that server receiving
 * the proxy can determine true client origin.
 */
static void
journal_add(const char *journal_dir, struct proxy_connection *pc, struct proxy_connection *cp)
{
    struct gc_arena gc = gc_new();
    struct openvpn_sockaddr from, to;
    socklen_t slen, dlen;
    int fnlen;
    char *jfn;
    int fd;

    slen = sizeof(from.addr.sa);
    dlen = sizeof(to.addr.sa);
    if (!getpeername(pc->sd, (struct sockaddr *) &from.addr.sa, &slen)
            && !getsockname(cp->sd, (struct sockaddr *) &to.addr.sa, &dlen))
    {
        const char *f = print_openvpn_sockaddr(&from, &gc);
        const char *t = print_openvpn_sockaddr(&to, &gc);
        fnlen =  strlen(journal_dir) + strlen(t) + 2;
        jfn = (char *) malloc(fnlen);
        check_malloc_return(jfn);
        openvpn_snprintf(jfn, fnlen, "%s/%s", journal_dir, t);
        dmsg(D_PS_PROXY_DEBUG, "PORT SHARE PROXY: client origin %s -> %s", jfn, f);
        fd = platform_open(jfn, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP);
        if (fd != -1)
        {
            if (write(fd, f, strlen(f)) != strlen(f))
            {
                msg(M_WARN, "PORT SHARE: writing to journal file (%s) failed", jfn);
            }
            close(fd);
            cp->jfn = jfn;
        }
        else
        {
            msg(M_WARN|M_ERRNO, "PORT SHARE: unable to write journal file in %s", jfn);
            free(jfn);
        }
    }
    gc_free(&gc);
}
static void err_put_ms_error(DWORD ms_err, int func, const char *file, int line)
{
    static int init = 0;
#   define ERR_MAP_SZ 16
    static struct {
	int err;
	DWORD ms_err;	    /* I don't think we get more than 16 *different* errors */
    } err_map[ERR_MAP_SZ];  /* in here, before we give up the whole thing...        */
    int i;

    if (ms_err == 0)
	/* 0 is not an error */
	return;
    if (!init) {
	ERR_load_strings(ERR_LIB_CRYPTOAPI, CRYPTOAPI_str_functs);
	memset(&err_map, 0, sizeof(err_map));
	init++;
    }
    /* since MS error codes are 32 bit, and the ones in the ERR_... system is
     * only 12, we must have a mapping table between them.  */
    for (i = 0; i < ERR_MAP_SZ; i++) {
	if (err_map[i].ms_err == ms_err) {
	    ERR_PUT_error(ERR_LIB_CRYPTOAPI, func, err_map[i].err, file, line);
	    break;
	} else if (err_map[i].ms_err == 0 ) {
	    /* end of table, add new entry */
	    ERR_STRING_DATA *esd = calloc(2, sizeof(*esd));
	    if (esd == NULL)
		break;
	    err_map[i].ms_err = ms_err;
	    err_map[i].err = esd->error = i + 100;
	    esd->string = ms_error_text(ms_err);
	    check_malloc_return(esd->string);
	    ERR_load_strings(ERR_LIB_CRYPTOAPI, esd);
	    ERR_PUT_error(ERR_LIB_CRYPTOAPI, func, err_map[i].err, file, line);
	    break;
	}
    }
}
Esempio n. 25
0
char *
_openssl_get_subject (X509 *cert, char *buf, int size)
{
  BIO *subject_bio = NULL;
  BUF_MEM *subject_mem;
  char *subject = buf;
  int maxlen = size;

  subject_bio = BIO_new (BIO_s_mem ());
  if (subject_bio == NULL)
    goto err;

  X509_NAME_print_ex (subject_bio, X509_get_subject_name (cert),
                      0, XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_FN_SN |
                      ASN1_STRFLGS_UTF8_CONVERT | ASN1_STRFLGS_ESC_CTRL);

  if (BIO_eof (subject_bio))
    goto err;

  BIO_get_mem_ptr (subject_bio, &subject_mem);
  if (subject == NULL)
    {
      maxlen = subject_mem->length + 1;
      subject = malloc (maxlen);
      check_malloc_return (subject);
    }

  memcpy (subject, subject_mem->data, maxlen);
  subject[maxlen - 1] = '\0';

err:
  if (subject_bio)
    BIO_free (subject_bio);

  return subject;
}
Esempio n. 26
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 in_addr_t server_addr,
			     const int server_port,
			     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,
				   server_port,
				   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;
}
Esempio n. 27
0
/*
 * Send a command (char), data (head), and a file descriptor (sd_send) to a local process
 * over unix socket sd.  Unfortunately, there's no portable way to send file descriptors
 * to other processes, so this code, as well as its analog (control_message_from_parent below),
 * is Linux-specific. This function runs in the context of the main process and is used to
 * send commands, data, and file descriptors to the background process.
 */
static void
port_share_sendmsg (const socket_descriptor_t sd,
		    const char command,
		    const struct buffer *head,
		    const socket_descriptor_t sd_send)
{
  if (socket_defined (sd))
    {
      struct msghdr mesg;
      struct cmsghdr* h;
      struct iovec iov[2];
      socket_descriptor_t sd_null[2] = { SOCKET_UNDEFINED, SOCKET_UNDEFINED };
      char cmd;
      ssize_t status;

      dmsg (D_PS_PROXY_DEBUG, "PORT SHARE: sendmsg sd=%d len=%d",
	    (int)sd_send,
	    head ? BLEN(head) : -1);

      CLEAR (mesg);

      cmd = command;

      iov[0].iov_base = &cmd;
      iov[0].iov_len = sizeof (cmd);
      mesg.msg_iovlen = 1;

      if (head)
	{
	  iov[1].iov_base = BPTR (head);
	  iov[1].iov_len = BLEN (head);
	  mesg.msg_iovlen = 2;
	}

      mesg.msg_iov = iov;

      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_level = SOL_SOCKET;
      h->cmsg_type = SCM_RIGHTS;
      h->cmsg_len = CMSG_LEN(sizeof(socket_descriptor_t));

      if (socket_defined (sd_send))
	{
	  *((socket_descriptor_t*)CMSG_DATA(h)) = sd_send;
	}
      else
	{
	  socketpair (PF_UNIX, SOCK_DGRAM, 0, sd_null);
	  *((socket_descriptor_t*)CMSG_DATA(h)) = sd_null[0];
	}

      status = sendmsg (sd, &mesg, MSG_NOSIGNAL);
      if (status == -1)
	msg (M_WARN|M_ERRNO, "PORT SHARE: sendmsg failed -- unable to communicate with background process (%d,%d,%d,%d)",
	     sd, sd_send, sd_null[0], sd_null[1]
	     );

      close_socket_if_defined (sd_null[0]);
      close_socket_if_defined (sd_null[1]);
      free (mesg.msg_control);
    }
}