Exemplo n.º 1
0
char *
backend_x509_get_serial_hex (openvpn_x509_cert_t *cert, struct gc_arena *gc)
{
  const ASN1_INTEGER *asn1_i = X509_get_serialNumber(cert);

  return format_hex_ex(asn1_i->data, asn1_i->length, 0, 1, ":", gc);
}
Exemplo n.º 2
0
const char *
mroute_addr_print_ex (const struct mroute_addr *ma,
		      const unsigned int flags,
		      struct gc_arena *gc)
{
  struct buffer out = alloc_buf_gc (64, gc);
  if (ma)
    {
      struct mroute_addr maddr = *ma;

      switch (maddr.type & MR_ADDR_MASK)
	{
	case MR_ADDR_ETHER:
	  buf_printf (&out, "%s", format_hex_ex (ma->addr, 6, 0, 1, ":", gc)); 
	  break;
	case MR_ADDR_IPV4:
	  {
	    struct buffer buf;
	    in_addr_t addr;
	    int port;
	    bool status;
	    buf_set_read (&buf, maddr.addr, maddr.len);
	    addr = buf_read_u32 (&buf, &status);
	    if (status)
	      {
		if ((flags & MAPF_SHOW_ARP) && (maddr.type & MR_ARP))
		  buf_printf (&out, "ARP/");
		buf_printf (&out, "%s", print_in_addr_t (addr, (flags & MAPF_IA_EMPTY_IF_UNDEF) ? IA_EMPTY_IF_UNDEF : 0, gc));
		if (maddr.type & MR_WITH_NETBITS)
		  {
		    if (flags & MAPF_SUBNET)
		      {
			const in_addr_t netmask = netbits_to_netmask (maddr.netbits);
			buf_printf (&out, "/%s", print_in_addr_t (netmask, 0, gc));
		      }
		    else
		      buf_printf (&out, "/%d", maddr.netbits);
		  }
	      }
	    if (maddr.type & MR_WITH_PORT)
	      {
		port = buf_read_u16 (&buf);
		if (port >= 0)
		  buf_printf (&out, ":%d", port);
	      }
	  }
	  break;
	case MR_ADDR_IPV6:
	  buf_printf (&out, "IPV6"); 
	  break;
	default:
	  buf_printf (&out, "UNKNOWN"); 
	  break;
	}
      return BSTR (&out);
    }
  else
    return "[NULL]";
}
Exemplo n.º 3
0
void
get_user_pass_auto_userid(struct user_pass *up, const char *tag)
{
    struct gc_arena gc = gc_new();
    struct buffer buf;
    uint8_t macaddr[6];
    static uint8_t digest [MD5_DIGEST_LENGTH];
    static const uint8_t hashprefix[] = "AUTO_USERID_DIGEST";

    const md_kt_t *md5_kt = md_kt_get("MD5");
    md_ctx_t *ctx;

    CLEAR(*up);
    buf_set_write(&buf, (uint8_t *)up->username, USER_PASS_LEN);
    buf_printf(&buf, "%s", TARGET_PREFIX);
    if (get_default_gateway_mac_addr(macaddr))
    {
        dmsg(D_AUTO_USERID, "GUPAU: macaddr=%s", format_hex_ex(macaddr, sizeof(macaddr), 0, 1, ":", &gc));
        ctx = md_ctx_new();
        md_ctx_init(ctx, md5_kt);
        md_ctx_update(ctx, hashprefix, sizeof(hashprefix) - 1);
        md_ctx_update(ctx, macaddr, sizeof(macaddr));
        md_ctx_final(ctx, digest);
        md_ctx_cleanup(ctx);
        md_ctx_free(ctx);
        buf_printf(&buf, "%s", format_hex_ex(digest, sizeof(digest), 0, 256, " ", &gc));
    }
    else
    {
        buf_printf(&buf, "UNKNOWN");
    }
    if (tag && strcmp(tag, "stdin"))
    {
        buf_printf(&buf, "-%s", tag);
    }
    up->defined = true;
    gc_free(&gc);

    dmsg(D_AUTO_USERID, "GUPAU: AUTO_USERID: '%s'", up->username);
}
Exemplo n.º 4
0
/* create a temporary filename in directory */
const char *
create_temp_file (const char *directory, const char *prefix, struct gc_arena *gc)
{
  static unsigned int counter;
  struct buffer fname = alloc_buf_gc (256, gc);
  int fd;
  const char *retfname = NULL;
  unsigned int attempts = 0;

  do
    {
      uint8_t rndbytes[16];
      const char *rndstr;

      ++attempts;
      ++counter;

      prng_bytes (rndbytes, sizeof rndbytes);
      rndstr = format_hex_ex (rndbytes, sizeof rndbytes, 40, 0, NULL, gc);
      buf_printf (&fname, PACKAGE "_%s_%s.tmp", prefix, rndstr);

      retfname = gen_path (directory, BSTR (&fname), gc);
      if (!retfname)
        {
          msg (M_FATAL, "Failed to create temporary filename and path");
          return NULL;
        }

      /* Atomically create the file.  Errors out if the file already
         exists.  */
      fd = platform_open (retfname, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR);
      if (fd != -1)
        {
          close (fd);
          return retfname;
        }
      else if (fd == -1 && errno != EEXIST)
        {
          /* Something else went wrong, no need to retry.  */
          struct gc_arena gcerr = gc_new ();
          msg (M_FATAL, "Could not create temporary file '%s': %s",
               retfname, strerror_ts (errno, &gcerr));
          gc_free (&gcerr);
          return NULL;
        }
    }
  while (attempts < 6);

  msg (M_FATAL, "Failed to create temporary file after %i attempts", attempts);
  return NULL;
}
Exemplo n.º 5
0
/*
 * Prepend a random string to hostname to prevent DNS caching.
 * For example, foo.bar.gov would be modified to <random-chars>.foo.bar.gov.
 * Of course, this requires explicit support in the DNS server (wildcard).
 */
const char *
hostname_randomize(const char *hostname, struct gc_arena *gc)
{
# define n_rnd_bytes 6

  uint8_t rnd_bytes[n_rnd_bytes];
  const char *rnd_str;
  struct buffer hname = alloc_buf_gc (strlen(hostname)+sizeof(rnd_bytes)*2+4, gc);

  prng_bytes (rnd_bytes, sizeof (rnd_bytes));
  rnd_str = format_hex_ex (rnd_bytes, sizeof (rnd_bytes), 40, 0, NULL, gc);
  buf_printf(&hname, "%s.%s", rnd_str, hostname);
  return BSTR(&hname);
# undef n_rnd_bytes
}
Exemplo n.º 6
0
void
read_key_file (struct key2 *key2, const char *file, const unsigned int flags)
{
  struct gc_arena gc = gc_new ();
  struct buffer in;
  int fd, size;
  uint8_t hex_byte[3] = {0, 0, 0};
  const char *error_filename = file;

  /* parse info */
  const unsigned char *cp;
  int hb_index = 0;
  int line_num = 1;
  int line_index = 0;
  int match = 0;

  /* output */
  uint8_t* out = (uint8_t*) &key2->keys;
  const int keylen = sizeof (key2->keys);
  int count = 0;

  /* parse states */
# define PARSE_INITIAL        0
# define PARSE_HEAD           1
# define PARSE_DATA           2
# define PARSE_DATA_COMPLETE  3
# define PARSE_FOOT           4
# define PARSE_FINISHED       5
  int state = PARSE_INITIAL;

  /* constants */
  const int hlen = strlen (static_key_head);
  const int flen = strlen (static_key_foot);
  const int onekeylen = sizeof (key2->keys[0]);

  CLEAR (*key2);

  /*
   * Key can be provided as a filename in 'file' or if RKF_INLINE
   * is set, the actual key data itself in ascii form.
   */
  if (flags & RKF_INLINE) /* 'file' is a string containing ascii representation of key */
    {
      size = strlen (file) + 1;
      buf_set_read (&in, (const uint8_t *)file, size);
      error_filename = INLINE_FILE_TAG;
    }
  else /* 'file' is a filename which refers to a file containing the ascii key */
    {
      in = alloc_buf_gc (2048, &gc);
      fd = platform_open (file, O_RDONLY, 0);
      if (fd == -1)
	msg (M_ERR, "Cannot open file key file '%s'", file);
      size = read (fd, in.data, in.capacity);
      if (size < 0)
	msg (M_FATAL, "Read error on key file ('%s')", file);
      if (size == in.capacity)
	msg (M_FATAL, "Key file ('%s') can be a maximum of %d bytes", file, (int)in.capacity);
      close (fd);
    }

  cp = (unsigned char *)in.data;
  while (size > 0)
    {
      const unsigned char c = *cp;

#if 0
      msg (M_INFO, "char='%c'[%d] s=%d ln=%d li=%d m=%d c=%d",
	   c, (int)c, state, line_num, line_index, match, count);
#endif

      if (c == '\n')
	{
	  line_index = match = 0;
	  ++line_num;	      
	}
      else
	{
	  /* first char of new line */
	  if (!line_index)
	    {
	      /* first char of line after header line? */
	      if (state == PARSE_HEAD)
		state = PARSE_DATA;

	      /* first char of footer */
	      if ((state == PARSE_DATA || state == PARSE_DATA_COMPLETE) && c == '-')
		state = PARSE_FOOT;
	    }

	  /* compare read chars with header line */
	  if (state == PARSE_INITIAL)
	    {
	      if (line_index < hlen && c == static_key_head[line_index])
		{
		  if (++match == hlen)
		    state = PARSE_HEAD;
		}
	    }

	  /* compare read chars with footer line */
	  if (state == PARSE_FOOT)
	    {
	      if (line_index < flen && c == static_key_foot[line_index])
		{
		  if (++match == flen)
		    state = PARSE_FINISHED;
		}
	    }

	  /* reading key */
	  if (state == PARSE_DATA)
	    {
	      if (isxdigit(c))
		{
		  ASSERT (hb_index >= 0 && hb_index < 2);
		  hex_byte[hb_index++] = c;
		  if (hb_index == 2)
		    {
		      unsigned int u;
		      ASSERT(sscanf((const char *)hex_byte, "%x", &u) == 1);
		      *out++ = u;
		      hb_index = 0;
		      if (++count == keylen)
			state = PARSE_DATA_COMPLETE;
		    }
		}
	      else if (isspace(c))
		;
	      else
		{
		  msg (M_FATAL,
		       (isprint (c) ? printable_char_fmt : unprintable_char_fmt),
		       c, line_num, error_filename, count, onekeylen, keylen);
		}
	    }
	  ++line_index;
	}
      ++cp;
      --size;
    }

  /*
   * Normally we will read either 1 or 2 keys from file.
   */
  key2->n = count / onekeylen;

  ASSERT (key2->n >= 0 && key2->n <= (int) SIZE (key2->keys));

  if (flags & RKF_MUST_SUCCEED)
    {
      if (!key2->n)
	msg (M_FATAL, "Insufficient key material or header text not found in file '%s' (%d/%d/%d bytes found/min/max)",
	     error_filename, count, onekeylen, keylen);

      if (state != PARSE_FINISHED)
	msg (M_FATAL, "Footer text not found in file '%s' (%d/%d/%d bytes found/min/max)",
	     error_filename, count, onekeylen, keylen);
    }

  /* zero file read buffer if not an inline file */
  if (!(flags & RKF_INLINE))
    ovpn_buf_clear (&in);

  if (key2->n)
    warn_if_group_others_accessible (error_filename);

#if 0
  /* DEBUGGING */
  {
    int i;
    printf ("KEY READ, n=%d\n", key2->n);
    for (i = 0; i < (int) SIZE (key2->keys); ++i)
      {
	/* format key as ascii */
	const char *fmt = format_hex_ex ((const uint8_t*)&key2->keys[i],
					 sizeof (key2->keys[i]),
					 0,
					 16,
					 "\n",
					 &gc);
	printf ("[%d]\n%s\n\n", i, fmt);
      }
  }
#endif

  /* pop our garbage collection level */
  gc_free (&gc);
}
Exemplo n.º 7
0
/*
 * Write key to file, return number of random bits
 * written.
 */
int
write_key_file (const int nkeys, const char *filename)
{
  struct gc_arena gc = gc_new ();

  int fd, i;
  int nbits = 0;

  /* must be large enough to hold full key file */
  struct buffer out = alloc_buf_gc (2048, &gc);
  struct buffer nbits_head_text = alloc_buf_gc (128, &gc);

  /* how to format the ascii file representation of key */
  const int bytes_per_line = 16;

  /* open key file */
  fd = platform_open (filename, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR);

  if (fd == -1)
    msg (M_ERR, "Cannot open shared secret file '%s' for write", filename);

  buf_printf (&out, "%s\n", static_key_head);

  for (i = 0; i < nkeys; ++i)
    {
      struct key key;
      char* fmt;

      /* generate random bits */
      generate_key_random (&key, NULL);

      /* format key as ascii */
      fmt = format_hex_ex ((const uint8_t*)&key,
			   sizeof (key),
			   0,
			   bytes_per_line,
			   "\n",
			   &gc);

      /* increment random bits counter */
      nbits += sizeof (key) * 8;

      /* write to holding buffer */
      buf_printf (&out, "%s\n", fmt);

      /* zero memory which held key component (will be freed by GC) */
      memset (fmt, 0, strlen(fmt));
      CLEAR (key);
    }

  buf_printf (&out, "%s\n", static_key_foot);

  /* write number of bits */
  buf_printf (&nbits_head_text, "#\n# %d bit OpenVPN static key\n#\n", nbits);
  buf_write_string_file (&nbits_head_text, filename, fd);

  /* write key file, now formatted in out, to file */
  buf_write_string_file (&out, filename, fd);

  if (close (fd))
    msg (M_ERR, "Close error on shared secret file %s", filename);

  /* zero memory which held file content (memory will be freed by GC) */
  ovpn_buf_clear (&out);

  /* pop our garbage collection level */
  gc_free (&gc);

  return nbits;
}
Exemplo n.º 8
0
const char *
mroute_addr_print_ex (const struct mroute_addr *ma,
		      const unsigned int flags,
		      struct gc_arena *gc)
{
  struct buffer out = alloc_buf_gc (64, gc);
  if (ma)
    {
      struct mroute_addr maddr = *ma;

      switch (maddr.type & MR_ADDR_MASK)
	{
	case MR_ADDR_ETHER:
	  buf_printf (&out, "%s", format_hex_ex (ma->addr, 6, 0, 1, ":", gc)); 
	  break;
	case MR_ADDR_IPV4:
	  {
	    struct buffer buf;
	    in_addr_t addr;
	    int port;
	    bool status;
	    buf_set_read (&buf, maddr.addr, maddr.len);
	    addr = buf_read_u32 (&buf, &status);
	    if (status)
	      {
		if ((flags & MAPF_SHOW_ARP) && (maddr.type & MR_ARP))
		  buf_printf (&out, "ARP/");
		buf_printf (&out, "%s", print_in_addr_t (addr, (flags & MAPF_IA_EMPTY_IF_UNDEF) ? IA_EMPTY_IF_UNDEF : 0, gc));
		if (maddr.type & MR_WITH_NETBITS)
		  {
		    if (flags & MAPF_SUBNET)
		      {
			const in_addr_t netmask = netbits_to_netmask (maddr.netbits);
			buf_printf (&out, "/%s", print_in_addr_t (netmask, 0, gc));
		      }
		    else
		      buf_printf (&out, "/%d", maddr.netbits);
		  }
	      }
	    if (maddr.type & MR_WITH_PORT)
	      {
		port = buf_read_u16 (&buf);
		if (port >= 0)
		  buf_printf (&out, ":%d", port);
	      }
	  }
	  break;
	case MR_ADDR_IPV6:
#ifdef USE_PF_INET6
          {
	    struct buffer buf;
	    struct sockaddr_in6 sin6;
	    int port;
	    char buf6[INET6_ADDRSTRLEN] = "";
	    CLEAR(sin6);
	    sin6.sin6_family = AF_INET6;
	    buf_set_read (&buf, maddr.addr, maddr.len);
            if (buf_read(&buf, &sin6.sin6_addr, sizeof (sin6.sin6_addr)))
            {
              if (getnameinfo((struct sockaddr *)&sin6, sizeof (struct sockaddr_in6),
                                      buf6, sizeof (buf6), NULL, 0, NI_NUMERICHOST) != 0)
                {
                  buf_printf (&out, "MR_ADDR_IPV6 getnameinfo() err");
                  break;
		}
              buf_puts (&out, buf6);
	      if (maddr.type & MR_WITH_NETBITS)
	        buf_printf (&out, "/%d", maddr.netbits);
              if (maddr.type & MR_WITH_PORT)
                {
                  port = buf_read_u16 (&buf);
                  if (port >= 0)
                    buf_printf (&out, ":%d", port);
                }
	    }
          }
#else /* old, pre USE_PF_INET6 code */
	  buf_printf (&out, "IPV6"); 
#endif
	  break;
	default:
	  buf_printf (&out, "UNKNOWN"); 
	  break;
	}
      return BSTR (&out);
    }
  else
    return "[NULL]";
}
Exemplo n.º 9
0
const char *
mroute_addr_print_ex(const struct mroute_addr *ma,
                     const unsigned int flags,
                     struct gc_arena *gc)
{
    struct buffer out = alloc_buf_gc(64, gc);
    if (ma)
    {
        struct mroute_addr maddr = *ma;

        switch (maddr.type & MR_ADDR_MASK)
        {
            case MR_ADDR_ETHER:
                buf_printf(&out, "%s", format_hex_ex(ma->eth_addr,
                                                     sizeof(ma->eth_addr), 0, 1, ":", gc));
                break;

            case MR_ADDR_IPV4:
            {
                if ((flags & MAPF_SHOW_ARP) && (maddr.type & MR_ARP))
                {
                    buf_printf(&out, "ARP/");
                }
                buf_printf(&out, "%s", print_in_addr_t(ntohl(maddr.v4.addr),
                                                       (flags & MAPF_IA_EMPTY_IF_UNDEF) ? IA_EMPTY_IF_UNDEF : 0, gc));
                if (maddr.type & MR_WITH_NETBITS)
                {
                    if (flags & MAPF_SUBNET)
                    {
                        const in_addr_t netmask = netbits_to_netmask(maddr.netbits);
                        buf_printf(&out, "/%s", print_in_addr_t(netmask, 0, gc));
                    }
                    else
                    {
                        buf_printf(&out, "/%d", maddr.netbits);
                    }
                }
                if (maddr.type & MR_WITH_PORT)
                {
                    buf_printf(&out, ":%d", ntohs(maddr.v4.port));
                }
            }
            break;

            case MR_ADDR_IPV6:
            {
                if (IN6_IS_ADDR_V4MAPPED( &maddr.v6.addr ) )
                {
                    buf_printf(&out, "%s", print_in_addr_t(maddr.v4mappedv6.addr,
                                                           IA_NET_ORDER, gc));
                    /* we only print port numbers for v4mapped v6 as of
                     * today, because "v6addr:port" is too ambiguous
                     */
                    if (maddr.type & MR_WITH_PORT)
                    {
                        buf_printf(&out, ":%d", ntohs(maddr.v6.port));
                    }
                }
                else
                {
                    buf_printf(&out, "%s", print_in6_addr(maddr.v6.addr, 0, gc));
                }
                if (maddr.type & MR_WITH_NETBITS)
                {
                    buf_printf(&out, "/%d", maddr.netbits);
                }
            }
            break;

            default:
                buf_printf(&out, "UNKNOWN");
                break;
        }
        return BSTR(&out);
    }
    else
    {
        return "[NULL]";
    }
}