Exemplo n.º 1
0
/*
 * Make safe mutations to key to ensure it is valid,
 * such as ensuring correct parity on DES keys.
 *
 * This routine cannot guarantee it will generate a good
 * key.  You must always call check_key after this routine
 * to make sure.
 */ 
void
fixup_key (struct key *key, const struct key_type *kt)
{
  struct gc_arena gc = gc_new ();
  if (kt->cipher)
    {
#ifdef ENABLE_DEBUG
      const struct key orig = *key;
#endif
      const int ndc = key_des_num_cblocks (kt->cipher);

      if (ndc)
	key_des_fixup (key->cipher, kt->cipher_length, ndc);

#ifdef ENABLE_DEBUG
      if (check_debug_level (D_CRYPTO_DEBUG))
	{
	  if (memcmp (orig.cipher, key->cipher, kt->cipher_length))
	    dmsg (D_CRYPTO_DEBUG, "CRYPTO INFO: fixup_key: before=%s after=%s",
		 format_hex (orig.cipher, kt->cipher_length, 0, &gc),
		 format_hex (key->cipher, kt->cipher_length, 0, &gc));
	}
#endif
    }
  gc_free (&gc);
}
Exemplo n.º 2
0
/*
 * Generate a random key.  If key_type is provided, make
 * sure generated key is valid for key_type.
 */
void
generate_key_random (struct key *key, const struct key_type *kt)
{
  int cipher_len = MAX_CIPHER_KEY_LENGTH;
  int hmac_len = MAX_HMAC_KEY_LENGTH;

  struct gc_arena gc = gc_new ();

  do {
    CLEAR (*key);
    if (kt)
      {
	if (kt->cipher && kt->cipher_length > 0 && kt->cipher_length <= cipher_len)
	  cipher_len = kt->cipher_length;

	if (kt->digest && kt->hmac_length > 0 && kt->hmac_length <= hmac_len)
	  hmac_len = kt->hmac_length;
      }
    if (!rand_bytes (key->cipher, cipher_len)
	|| !rand_bytes (key->hmac, hmac_len))
      msg (M_FATAL, "ERROR: Random number generator cannot obtain entropy for key generation");

    dmsg (D_SHOW_KEY_SOURCE, "Cipher source entropy: %s", format_hex (key->cipher, cipher_len, 0, &gc));
    dmsg (D_SHOW_KEY_SOURCE, "HMAC source entropy: %s", format_hex (key->hmac, hmac_len, 0, &gc));

    if (kt)
      fixup_key (key, kt);
  } while (kt && !check_key (key, kt));

  gc_free (&gc);
}
Exemplo n.º 3
0
// show_vote
//     called when the SYSFS file is accessed.
//
// SYSFS attributes,
// "/sys/class/usb/vote0/device/voting" is read
//
//	tvote vs. vote_dev vs usb_vote - chose vote_dev --kgb
//
static ssize_t
show_vote(
    struct device *dev,
    struct device_attribute *attr,
    char * buf
) {
    int bytes = 0;	// bytes written to buf by sprintf
    			// not including final '\0'
    struct usb_interface *intf = to_usb_interface(dev);
    struct usb_vote * vote_dev = usb_get_intfdata(intf);
    char page[100];	// sysfs output
    char vstring[10];	// vote as a string

    // Print the vote -- if its printable and not whitespace.
    if (vote_dev->votecast >= '!' && vote_dev->votecast <= '~') {
	bytes = sprintf(page, "Current vote: %c.  ", vote_dev->votecast);
    }
    printk(KERN_DEBUG "%s with bytes=%d, page=\"%s\"\n",
                      __FUNCTION__, bytes, page);
    // Print out the hex value of the vote
    sprintf(vstring, "%c", vote_dev->votecast);
    format_hex(&page[bytes], 1, vstring);

    bytes = sprintf(buf, "%s\n", page);
    printk(KERN_DEBUG "%s with bytes=%d, buf=\"%s\"\n",
                      __FUNCTION__, bytes, buf);

    return bytes;
} // show_vote()
Exemplo n.º 4
0
/* given a key and key_type, build a key_ctx */
void
init_key_ctx (struct key_ctx *ctx, struct key *key,
	      const struct key_type *kt, int enc,
	      const char *prefix)
{
  struct gc_arena gc = gc_new ();
  CLEAR (*ctx);
  if (kt->cipher && kt->cipher_length > 0)
    {

      ALLOC_OBJ(ctx->cipher, cipher_ctx_t);
      cipher_ctx_init (ctx->cipher, key->cipher, kt->cipher_length,
	  kt->cipher, enc);

      msg (D_HANDSHAKE, "%s: Cipher '%s' initialized with %d bit key",
          prefix,
          cipher_kt_name(kt->cipher),
          kt->cipher_length *8);

      dmsg (D_SHOW_KEYS, "%s: CIPHER KEY: %s", prefix,
          format_hex (key->cipher, kt->cipher_length, 0, &gc));
      dmsg (D_CRYPTO_DEBUG, "%s: CIPHER block_size=%d iv_size=%d",
          prefix,
          cipher_kt_block_size(kt->cipher),
          cipher_kt_iv_size(kt->cipher));
    }
  if (kt->digest && kt->hmac_length > 0)
    {
      ALLOC_OBJ(ctx->hmac, hmac_ctx_t);
      hmac_ctx_init (ctx->hmac, key->hmac, kt->hmac_length, kt->digest);

      msg (D_HANDSHAKE,
      "%s: Using %d bit message hash '%s' for HMAC authentication",
      prefix, md_kt_size(kt->digest) * 8, md_kt_name(kt->digest));

      dmsg (D_SHOW_KEYS, "%s: HMAC KEY: %s", prefix,
	  format_hex (key->hmac, kt->hmac_length, 0, &gc));

      dmsg (D_CRYPTO_DEBUG, "%s: HMAC size=%d block_size=%d",
	prefix,
	md_kt_size(kt->digest),
	hmac_ctx_size(ctx->hmac));

    }
  gc_free (&gc);
}
Exemplo n.º 5
0
static bool
tls_crypt_v2_wrap_client_key(struct buffer *wkc,
                             const struct key2 *src_key,
                             const struct buffer *src_metadata,
                             struct key_ctx *server_key, struct gc_arena *gc)
{
    cipher_ctx_t *cipher_ctx = server_key->cipher;
    struct buffer work = alloc_buf_gc(TLS_CRYPT_V2_MAX_WKC_LEN
                                      + cipher_ctx_block_size(cipher_ctx), gc);

    /* Calculate auth tag and synthetic IV */
    uint8_t *tag = buf_write_alloc(&work, TLS_CRYPT_TAG_SIZE);
    if (!tag)
    {
        msg(M_WARN, "ERROR: could not write tag");
        return false;
    }
    uint16_t net_len = htons(sizeof(src_key->keys) + BLEN(src_metadata)
                             + TLS_CRYPT_V2_TAG_SIZE + sizeof(uint16_t));
    hmac_ctx_t *hmac_ctx = server_key->hmac;
    hmac_ctx_reset(hmac_ctx);
    hmac_ctx_update(hmac_ctx, (void *)&net_len, sizeof(net_len));
    hmac_ctx_update(hmac_ctx, (void *)src_key->keys, sizeof(src_key->keys));
    hmac_ctx_update(hmac_ctx, BPTR(src_metadata), BLEN(src_metadata));
    hmac_ctx_final(hmac_ctx, tag);

    dmsg(D_CRYPTO_DEBUG, "TLS-CRYPT WRAP TAG: %s",
         format_hex(tag, TLS_CRYPT_TAG_SIZE, 0, gc));

    /* Use the 128 most significant bits of the tag as IV */
    ASSERT(cipher_ctx_reset(cipher_ctx, tag));

    /* Overflow check (OpenSSL requires an extra block in the dst buffer) */
    if (buf_forward_capacity(&work) < (sizeof(src_key->keys)
                                       + BLEN(src_metadata)
                                       + sizeof(net_len)
                                       + cipher_ctx_block_size(cipher_ctx)))
    {
        msg(M_WARN, "ERROR: could not crypt: insufficient space in dst");
        return false;
    }

    /* Encrypt */
    int outlen = 0;
    ASSERT(cipher_ctx_update(cipher_ctx, BEND(&work), &outlen,
                             (void *)src_key->keys, sizeof(src_key->keys)));
    ASSERT(buf_inc_len(&work, outlen));
    ASSERT(cipher_ctx_update(cipher_ctx, BEND(&work), &outlen,
                             BPTR(src_metadata), BLEN(src_metadata)));
    ASSERT(buf_inc_len(&work, outlen));
    ASSERT(cipher_ctx_final(cipher_ctx, BEND(&work), &outlen));
    ASSERT(buf_inc_len(&work, outlen));
    ASSERT(buf_write(&work, &net_len, sizeof(net_len)));

    return buf_copy(wkc, &work);
}
Exemplo n.º 6
0
const char *
md5sum (uint8_t *buf, int len, int n_print_chars, struct gc_arena *gc)
{
  uint8_t digest[MD5_DIGEST_LENGTH];
  const md_kt_t *md5_kt = md_kt_get("MD5");

  md_full(md5_kt, buf, len, digest);

  return format_hex (digest, MD5_DIGEST_LENGTH, n_print_chars, gc);
}
Exemplo n.º 7
0
format_hexdump::format_hexdump(const void * p_buffer,t_size p_bytes,const char * p_spacing)
{
	t_size n;
	const t_uint8 * buffer = (const t_uint8*)p_buffer;
	for(n=0;n<p_bytes;n++)
	{
		if (n > 0 && p_spacing != 0) m_formatter << p_spacing;
		m_formatter << format_hex(buffer[n],2);
	}
}
Exemplo n.º 8
0
static void
bio_debug_data (const char *mode, BIO *bio, const uint8_t *buf, int len, const char *desc)
{
  struct gc_arena gc = gc_new ();
  if (len > 0)
    {
      open_biofp();
      fprintf(biofp, "BIO_%s %s time=" time_format " bio=" ptr_format " len=%d data=%s\n",
	      mode, desc, time (NULL), (ptr_type)bio, len, format_hex (buf, len, 0, &gc));
      fflush (biofp);
    }
  gc_free (&gc);
}
Exemplo n.º 9
0
int
nrx_wxevent_connection_lost(struct net_device *dev, we_conn_lost_ind_t *data)
{
   char bssid[13];
   format_hex(bssid, sizeof(bssid), 
              data->bssid.octet, sizeof(data->bssid.octet));

   send_nrx_event(dev, "CONNLOST,type=%#x,bssid=%s,reason=%#x",
                  data->type,
                  bssid,
                  data->reason_code);
   return 0;
}
Exemplo n.º 10
0
/*
 * Print key material
 */
void
key2_print (const struct key2* k,
	    const struct key_type *kt,
	    const char* prefix0,
	    const char* prefix1)
{
  struct gc_arena gc = gc_new ();
  ASSERT (k->n == 2);
  dmsg (D_SHOW_KEY_SOURCE, "%s (cipher): %s",
       prefix0,
       format_hex (k->keys[0].cipher, kt->cipher_length, 0, &gc));
  dmsg (D_SHOW_KEY_SOURCE, "%s (hmac): %s",
       prefix0,
       format_hex (k->keys[0].hmac, kt->hmac_length, 0, &gc));
  dmsg (D_SHOW_KEY_SOURCE, "%s (cipher): %s",
       prefix1,
       format_hex (k->keys[1].cipher, kt->cipher_length, 0, &gc));
  dmsg (D_SHOW_KEY_SOURCE, "%s (hmac): %s",
       prefix1,
       format_hex (k->keys[1].hmac, kt->hmac_length, 0, &gc));
  gc_free (&gc);
}
Exemplo n.º 11
0
static int to_str(void *item,char *dst)
{
	mbag_item_t *i= item;

	char *d = dst;
	int utf8 = format_is_utf8(bstr16_data(i->data), bstr16_len(i->data));


        if (utf8) {
                d += sprintf(d, "%.*s", bstr16_len(i->data), bstr16_data(i->data));
        } else {
                d += sprintf(d, ".x");
                d += format_hex(d, bstr16_data(i->data), bstr16_len(i->data));
        }
	return d-dst;	
}
Exemplo n.º 12
0
static void
send_custom_event(struct net_device *dev,
                  const char *prefix, const char *suffix, 
                  void *buf, size_t len)
{
   union iwreq_data wrqu;
   char custom[IW_CUSTOM_MAX];
   size_t cend = 0;

   snprintf(custom, sizeof(custom), "%s", prefix);
   cend = strlen(custom);
   cend += format_hex(custom + cend, sizeof(custom) - cend, buf, len);
   cend += snprintf(custom + cend, sizeof(custom) - cend, "%s", suffix);
   wrqu.data.length = strlen(custom);
   wrqu.data.flags = 0;
   wrqu.data.pointer = (caddr_t)0xdeadbeef;
   wireless_send_event(dev, IWEVCUSTOM, &wrqu, custom);
}
Exemplo n.º 13
0
_format_hw_dn(char *buf, size_t size, const_efidp dp)
{
    efi_guid_t edd10_guid = EDD10_HARDWARE_VENDOR_PATH_GUID;
    off_t off = 0;
    switch (dp->subtype) {
    case EFIDP_HW_PCI:
        off += format(buf, size, off, "Pci(0x%"PRIx32",0x%"PRIx32")",
                      dp->pci.device, dp->pci.function);
        break;
    case EFIDP_HW_PCCARD:
        off += format(buf, size, off, "PcCard(0x%"PRIx32")",
                      dp->pccard.function);
        break;
    case EFIDP_HW_MMIO:
        off += format(buf, size, off,
                      "MemoryMapped(%"PRIu32",0x%"PRIx64",0x%"PRIx64")",
                      dp->mmio.memory_type, dp->mmio.starting_address,
                      dp->mmio.ending_address);
        break;
    case EFIDP_HW_VENDOR:
        if (!efi_guid_cmp(&dp->hw_vendor.vendor_guid, &edd10_guid)) {
            off += format_helper(format_edd10_guid, buf, size,
                                 off, dp);
        } else {
            off += format_vendor(buf, size, off, "VenHw", dp);
        }
        break;
    case EFIDP_HW_CONTROLLER:
        off += format(buf, size, off, "Ctrl(0x%"PRIx32")",
                      dp->controller.controller);
        break;
    case EFIDP_HW_BMC:
        off += format(buf, size, off, "BMC(%d,0x%"PRIx64")",
                      dp->bmc.interface_type, dp->bmc.base_addr);
        break;
    default:
        off += format(buf, size, off, "HardwarePath(%d,", dp->subtype);
        off += format_hex(buf, size, off, (uint8_t *)dp+4,
                          efidp_node_size(dp)-4);
        off += format(buf,size,off,")");
        break;
    }
    return off;
}
Exemplo n.º 14
0
void ObjDumper::SectionHexDump(StringRef SecName, const uint8_t *Section,
                               size_t Size) {
  const uint8_t *SecContent = Section;
  const uint8_t *SecEnd = Section + Size;
  W.startLine() << "Hex dump of section '" << SecName << "':\n";

  for (const uint8_t *SecPtr = SecContent; SecPtr < SecEnd; SecPtr += 16) {
    const uint8_t *TmpSecPtr = SecPtr;
    uint8_t i;
    uint8_t k;

    W.startLine() << format_hex(SecPtr - SecContent, 10);
    W.startLine() << ' ';
    for (i = 0; TmpSecPtr < SecEnd && i < 4; ++i) {
      for (k = 0; TmpSecPtr < SecEnd && k < 4; k++, TmpSecPtr++) {
        uint8_t Val = *(reinterpret_cast<const uint8_t *>(TmpSecPtr));
        W.startLine() << format_hex_no_prefix(Val, 2);
      }
      W.startLine() << ' ';
    }

    // We need to print the correct amount of spaces to match the format.
    // We are adding the (4 - i) last rows that are 8 characters each.
    // Then, the (4 - i) spaces that are in between the rows.
    // Least, if we cut in a middle of a row, we add the remaining characters,
    // which is (8 - (k * 2))
    if (i < 4)
      W.startLine() << format("%*c", (4 - i) * 8 + (4 - i) + (8 - (k * 2)),
                              ' ');

    TmpSecPtr = SecPtr;
    for (i = 0; TmpSecPtr + i < SecEnd && i < 16; ++i) {
      if (isprint(TmpSecPtr[i]))
        W.startLine() << TmpSecPtr[i];
      else
        W.startLine() << '.';
    }

    W.startLine() << '\n';
  }
}
Exemplo n.º 15
0
int
nrx_wxevent_michael_mic_failure(struct net_device *dev, 
				void *bssid, 
				int group_failure)
{
   unsigned int keyid = 0;
#if WIRELESS_EXT < 18
   char buf[128];
   char addr[32];
   format_hex(addr, sizeof(addr), bssid, 6);
   snprintf(buf, sizeof(buf), 
	    "MLME-MICHAELMICFAILURE.indication(keyid=%u %s addr=%s)",
	    keyid,
	    group_failure ? "broadcast" : "unicast",
	    addr);
   send_custom_event(dev, buf, "", NULL, 0);
   
#else
   struct iw_michaelmicfailure mic;
   union iwreq_data wrqu;

   wrqu.data.length = sizeof(mic);
   wrqu.data.flags = 0;

   mic.flags = keyid;
   if(group_failure)
      mic.flags |= IW_MICFAILURE_GROUP;
   else
      mic.flags |= IW_MICFAILURE_PAIRWISE;
   mic.src_addr.sa_family = ARPHRD_ETHER;
   memcpy(mic.src_addr.sa_data, bssid, 6);
   memset(mic.tsc, 0, sizeof(mic.tsc));

   wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char*)&mic);

#endif
   return 0;
}
static int
write_header(struct archive_write *a, struct archive_entry *entry)
{
	int64_t ino;
	struct cpio *cpio;
	const char *p, *path;
	int pathlength, ret, ret_final;
	char h[c_header_size];
	struct archive_string_conv *sconv;
	struct archive_entry *entry_main;
	size_t len;
	int pad;

	cpio = (struct cpio *)a->format_data;
	ret_final = ARCHIVE_OK;
	sconv = get_sconv(a);

#if defined(_WIN32) && !defined(__CYGWIN__)
	/* Make sure the path separators in pahtname, hardlink and symlink
	 * are all slash '/', not the Windows path separator '\'. */
	entry_main = __la_win_entry_in_posix_pathseparator(entry);
	if (entry_main == NULL) {
		archive_set_error(&a->archive, ENOMEM,
		    "Can't allocate ustar data");
		return(ARCHIVE_FATAL);
	}
	if (entry != entry_main)
		entry = entry_main;
	else
		entry_main = NULL;
#else
	entry_main = NULL;
#endif

	ret = archive_entry_pathname_l(entry, &path, &len, sconv);
	if (ret != 0) {
		if (errno == ENOMEM) {
			archive_set_error(&a->archive, ENOMEM,
			    "Can't allocate memory for Pathname");
			ret_final = ARCHIVE_FATAL;
			goto exit_write_header;
		}
		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
		    "Can't translate pathname '%s' to %s",
		    archive_entry_pathname(entry),
		    archive_string_conversion_charset_name(sconv));
		ret_final = ARCHIVE_WARN;
	}
	pathlength = (int)len + 1; /* Include trailing null. */

	memset(h, 0, c_header_size);
	format_hex(0x070701, h + c_magic_offset, c_magic_size);
	format_hex(archive_entry_devmajor(entry), h + c_devmajor_offset,
	    c_devmajor_size);
	format_hex(archive_entry_devminor(entry), h + c_devminor_offset,
	    c_devminor_size);

	ino = archive_entry_ino64(entry);
	if (ino > 0xffffffff) {
		archive_set_error(&a->archive, ERANGE,
		    "large inode number truncated");
		ret_final = ARCHIVE_WARN;
	}

	/* TODO: Set ret_final to ARCHIVE_WARN if any of these overflow. */
	format_hex(ino & 0xffffffff, h + c_ino_offset, c_ino_size);
	format_hex(archive_entry_mode(entry), h + c_mode_offset, c_mode_size);
	format_hex(archive_entry_uid(entry), h + c_uid_offset, c_uid_size);
	format_hex(archive_entry_gid(entry), h + c_gid_offset, c_gid_size);
	format_hex(archive_entry_nlink(entry), h + c_nlink_offset, c_nlink_size);
	if (archive_entry_filetype(entry) == AE_IFBLK
	    || archive_entry_filetype(entry) == AE_IFCHR) {
	    format_hex(archive_entry_rdevmajor(entry), h + c_rdevmajor_offset, c_rdevmajor_size);
	    format_hex(archive_entry_rdevminor(entry), h + c_rdevminor_offset, c_rdevminor_size);
	} else {
	    format_hex(0, h + c_rdevmajor_offset, c_rdevmajor_size);
	    format_hex(0, h + c_rdevminor_offset, c_rdevminor_size);
	}
	format_hex(archive_entry_mtime(entry), h + c_mtime_offset, c_mtime_size);
	format_hex(pathlength, h + c_namesize_offset, c_namesize_size);
	format_hex(0, h + c_checksum_offset, c_checksum_size);

	/* Non-regular files don't store bodies. */
	if (archive_entry_filetype(entry) != AE_IFREG)
		archive_entry_set_size(entry, 0);

	/* Symlinks get the link written as the body of the entry. */
	ret = archive_entry_symlink_l(entry, &p, &len, sconv);
	if (ret != 0) {
		if (errno == ENOMEM) {
			archive_set_error(&a->archive, ENOMEM,
			    "Can't allocate memory for Likname");
			ret_final = ARCHIVE_FATAL;
			goto exit_write_header;
		}
		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
		    "Can't translate linkname '%s' to %s",
		    archive_entry_symlink(entry),
		    archive_string_conversion_charset_name(sconv));
		ret_final = ARCHIVE_WARN;
	}
	if (len > 0 && p != NULL  &&  *p != '\0')
		ret = format_hex(strlen(p), h + c_filesize_offset,
		    c_filesize_size);
	else
		ret = format_hex(archive_entry_size(entry),
		    h + c_filesize_offset, c_filesize_size);
	if (ret) {
		archive_set_error(&a->archive, ERANGE,
		    "File is too large for this format.");
		ret_final = ARCHIVE_FAILED;
		goto exit_write_header;
	}

	ret = __archive_write_output(a, h, c_header_size);
	if (ret != ARCHIVE_OK) {
		ret_final = ARCHIVE_FATAL;
		goto exit_write_header;
	}

	/* Pad pathname to even length. */
	ret = __archive_write_output(a, path, pathlength);
	if (ret != ARCHIVE_OK) {
		ret_final = ARCHIVE_FATAL;
		goto exit_write_header;
	}
	pad = PAD4(pathlength + c_header_size);
	if (pad) {
		ret = __archive_write_output(a, "\0\0\0", pad);
		if (ret != ARCHIVE_OK) {
			ret_final = ARCHIVE_FATAL;
			goto exit_write_header;
		}
	}

	cpio->entry_bytes_remaining = archive_entry_size(entry);
	cpio->padding = (int)PAD4(cpio->entry_bytes_remaining);

	/* Write the symlink now. */
	if (p != NULL  &&  *p != '\0') {
		ret = __archive_write_output(a, p, strlen(p));
		if (ret != ARCHIVE_OK) {
			ret_final = ARCHIVE_FATAL;
			goto exit_write_header;
		}
		pad = PAD4(strlen(p));
		ret = __archive_write_output(a, "\0\0\0", pad);
		if (ret != ARCHIVE_OK) {
			ret_final = ARCHIVE_FATAL;
			goto exit_write_header;
		}
	}
exit_write_header:
	if (entry_main)
		archive_entry_free(entry_main);
	return (ret_final);
}
Exemplo n.º 17
0
_format_message_dn(char *buf, size_t size, const_efidp dp)
{
	ssize_t off = 0;
	ssize_t sz;
	switch (dp->subtype) {
	case EFIDP_MSG_ATAPI:
		off += format(buf, size, off, "Ata(%d,%d,%d)",
			      dp->atapi.primary, dp->atapi.slave,
			      dp->atapi.lun);
		break;
	case EFIDP_MSG_SCSI:
		off += format(buf, size, off, "SCSI(%d,%d)",
			      dp->scsi.target, dp->scsi.lun);
		break;
	case EFIDP_MSG_FIBRECHANNEL:
		off += format(buf, size, off, "Fibre(%"PRIx64",%"PRIx64")",
			      le64_to_cpu(dp->fc.wwn),
			      le64_to_cpu(dp->fc.lun));
		break;
	case EFIDP_MSG_FIBRECHANNELEX:
		off += format(buf, size, off, "Fibre(%"PRIx64",%"PRIx64")",
			      be64_to_cpu(dp->fc.wwn),
			      be64_to_cpu(dp->fc.lun));
		break;
	case EFIDP_MSG_1394:
		off += format(buf, size, off, "I1394(0x%"PRIx64")",
			      dp->firewire.guid);
		break;
	case EFIDP_MSG_USB:
		off += format(buf, size, off, "USB(%d,%d)",
			      dp->usb.parent_port, dp->usb.interface);
		break;
	case EFIDP_MSG_I2O:
		off += format(buf, size, off, "I2O(%d)", dp->i2o.target);
		break;
	case EFIDP_MSG_INFINIBAND:
		if (dp->infiniband.resource_flags &
				EFIDP_INFINIBAND_RESOURCE_IOC_SERVICE) {
			off += format(buf, size, off,
				      "Infiniband(%08x,%"PRIx64"%"PRIx64",%"PRIx64",%"PRIu64",%"PRIu64")",
				      dp->infiniband.resource_flags,
				      dp->infiniband.port_gid[1],
				      dp->infiniband.port_gid[0],
				      dp->infiniband.service_id,
				      dp->infiniband.target_port_id,
				      dp->infiniband.device_id);
		} else {
			off += format(buf, size, off,
				      "Infiniband(%08x,%"PRIx64"%"PRIx64",",
				      dp->infiniband.resource_flags,
				      dp->infiniband.port_gid[1],
				      dp->infiniband.port_gid[0]);
			off += format_guid(buf, size, off, (efi_guid_t *)
					   &dp->infiniband.ioc_guid);
			off += format(buf, size, off, ",%"PRIu64",%"PRIu64")",
				      dp->infiniband.target_port_id,
				      dp->infiniband.device_id);
		}
		break;
	case EFIDP_MSG_MAC_ADDR:
		off += format(buf, size, off, "MAC(");
		off += format_hex(buf, size, off, dp->mac_addr.mac_addr,
				  dp->mac_addr.if_type < 2 ? 6
					: sizeof(dp->mac_addr.mac_addr));
		off += format(buf, size, off, ",%d)", dp->mac_addr.if_type);
		break;
	case EFIDP_MSG_IPv4: {
		efidp_ipv4_addr const *a = &dp->ipv4_addr;
		off += format(buf, size, off,
			      "IPv4(%hhu.%hhu.%hhu.%hhu:%hu<->%hhu.%hhu.%hhu.%hhu:%hu,%hx,%hhx)",
			      a->local_ipv4_addr[0], a->local_ipv4_addr[1],
			      a->local_ipv4_addr[2], a->local_ipv4_addr[3],
			      a->local_port, a->remote_ipv4_addr[0],
			      a->remote_ipv4_addr[1], a->remote_ipv4_addr[2],
			      a->remote_ipv4_addr[3], a->remote_port,
			      a->protocol, a->static_ip_addr);
		break;
			     }
	case EFIDP_MSG_VENDOR: {
		struct {
			efi_guid_t guid;
			char label[40];
			ssize_t (*formatter)(char *buf, size_t size,
					     const_efidp dp);
		} subtypes[] = {
			{ EFIDP_PC_ANSI_GUID, "VenPcAnsi" },
			{ EFIDP_VT_100_GUID, "VenVt100" },
			{ EFIDP_VT_100_PLUS_GUID, "VenVt100Plus" },
			{ EFIDP_VT_UTF8_GUID, "VenUtf8" },
			{ EFIDP_MSG_DEBUGPORT_GUID, "DebugPort" },
			{ EFIDP_MSG_UART_GUID, "", format_uart },
			{ EFIDP_MSG_SAS_GUID, "", format_sas },
			{ efi_guid_empty, "" }
		};
		char *label = NULL;
		ssize_t (*formatter)(char *buf, size_t size,
				     const_efidp dp) = NULL;

		for (int i = 0; !efi_guid_is_zero(&subtypes[i].guid); i++) {
			if (efi_guid_cmp(&subtypes[i].guid,
					  &dp->msg_vendor.vendor_guid))
				continue;

			label = subtypes[i].label;
			formatter = subtypes[i].formatter;
			break;
		}

		if (!label && !formatter) {
			off += format_vendor(buf, size, off, "VenMsg", dp);
			break;
		} else if (formatter) {
			off += format_helper(formatter, buf, size, off, dp);
			break;
		}

		off += format(buf, size, off, "%s(", label);
		if (efidp_node_size(dp) >
				(ssize_t)(sizeof (efidp_header)
					  + sizeof (efi_guid_t))) {
			off += format_hex(buf, size, off,
					  dp->msg_vendor.vendor_data,
					  efidp_node_size(dp)
						- sizeof (efidp_header)
						- sizeof (efi_guid_t));
		}
		break;
			       }
	case EFIDP_MSG_IPv6: {
		efidp_ipv6_addr const *a = &dp->ipv6_addr;
		char *addr0 = NULL;
		char *addr1 = NULL;

		sz = format_ipv6_port(addr0, 0, 0, a->local_ipv6_addr,
				      a->local_port);
		if (sz < 0)
			return sz;

		addr0 = alloca(sz+1);
		sz = format_ipv6_port(addr0, sz, 0, a->local_ipv6_addr,
				      a->local_port);
		if (sz < 0)
			return sz;

		sz = format_ipv6_port(addr1, 0, 0, a->remote_ipv6_addr,
				      a->remote_port);
		if (sz < 0)
			return sz;
		addr1 = alloca(sz+1);
		sz = format_ipv6_port(addr1, sz, 0, a->remote_ipv6_addr,
				      a->remote_port);
		if (sz < 0)
			return sz;

		off += format(buf, size, off, "IPv6(%s<->%s,%hx,%hhx)",
			     addr0, addr1, a->protocol, a->ip_addr_origin);
		break;
			     }
	case EFIDP_MSG_UART: {
		int parity = dp->uart.parity;
		char parity_label[] = "DNEOMS";
		int stop_bits = dp->uart.stop_bits;
		char *sb_label[] = {"D", "1", "1.5", "2"};

		off += format(buf, size, off, "Uart(%"PRIu64",%d,",
			     dp->uart.baud_rate ? dp->uart.baud_rate : 115200,
			     dp->uart.data_bits ? dp->uart.data_bits : 8);
		off += format(buf, size, off,
			     parity > 5 ? "%d," : "%c,",
			     parity > 5 ? parity : parity_label[parity]);
		if (stop_bits > 3)
			off += format(buf, size, off, "%d)", stop_bits);
		else
			off += format(buf, size, off, "%s)",
				     sb_label[stop_bits]);
		break;
			     }
	case EFIDP_MSG_USB_CLASS:
		off += format_helper(format_usb_class, buf, size, off, dp);
		break;
	case EFIDP_MSG_USB_WWID:
		off += format(buf, size, off,
			      "UsbWwid(%"PRIx16",%"PRIx16",%d,",
			      dp->usb_wwid.vendor_id, dp->usb_wwid.product_id,
			      dp->usb_wwid.interface);
		off += format_ucs2(buf, size, off, dp->usb_wwid.serial_number,
				   (efidp_node_size(dp)
				    - offsetof(efidp_usb_wwid, serial_number))
				   / 2 + 1);
		off += format(buf, size, off, ")");
		break;
	case EFIDP_MSG_LUN:
		off += format(buf, size, off, "Unit(%d)", dp->lun.lun);
		break;
	case EFIDP_MSG_SATA:
		off += format(buf, size, off, "Sata(%d,%d,%d)",
			     dp->sata.hba_port, dp->sata.port_multiplier_port,
			     dp->sata.lun);
		break;
	case EFIDP_MSG_ISCSI: {
		size_t sz = efidp_node_size(dp)
			    - offsetof(efidp_iscsi, target_name);
		if (sz > EFIDP_ISCSI_MAX_TARGET_NAME_LEN)
			sz = EFIDP_ISCSI_MAX_TARGET_NAME_LEN;
		char target_name[sz + 1];
		memcpy(target_name, dp->iscsi.target_name, sz);
		target_name[sz] = '\0';
		uint64_t lun;

		memcpy(&lun, dp->iscsi.lun, sizeof (lun));

		off += format(buf, size, off,
			      "iSCSI(%s,%d,0x%"PRIx64",%s,%s,%s,%s)",
			      target_name, dp->iscsi.tpgt,
			      be64_to_cpu(lun),
			      (dp->iscsi.options >> EFIDP_ISCSI_HEADER_DIGEST_SHIFT) & EFIDP_ISCSI_HEADER_CRC32 ? "CRC32" : "None",
			      (dp->iscsi.options >> EFIDP_ISCSI_DATA_DIGEST_SHIFT) & EFIDP_ISCSI_DATA_CRC32 ? "CRC32" : "None",
			      (dp->iscsi.options >> EFIDP_ISCSI_AUTH_SHIFT) & EFIDP_ISCSI_AUTH_NONE ? "None" : \
				      (dp->iscsi.options >> EFIDP_ISCSI_CHAP_SHIFT) & EFIDP_ISCSI_CHAP_UNI ? "CHAP_UNI" : "CHAP_BI",
			      dp->iscsi.protocol == 0 ? "TCP" : "Unknown");
		break;
			      }
	case EFIDP_MSG_VLAN:
		off += format(buf, size, off, "Vlan(%d)", dp->vlan.vlan_id);
		break;
	case EFIDP_MSG_SAS_EX:
		off += format_sas(buf, size, dp);
		break;
	case EFIDP_MSG_NVME:
		off += format(buf, size, off, "NVMe(0x%"PRIx32","
			      "%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X)",
			      dp->nvme.namespace_id, dp->nvme.ieee_eui_64[0],
			      dp->nvme.ieee_eui_64[1], dp->nvme.ieee_eui_64[2],
			      dp->nvme.ieee_eui_64[3], dp->nvme.ieee_eui_64[4],
			      dp->nvme.ieee_eui_64[5], dp->nvme.ieee_eui_64[6],
			      dp->nvme.ieee_eui_64[7]);
		break;
	case EFIDP_MSG_URI: {
		size_t sz = efidp_node_size(dp) - offsetof(efidp_uri, uri);
		char uri[sz + 1];
		memcpy(uri, dp->uri.uri, sz);
		uri[sz] = '\0';
		off += format(buf, size, off, "Uri(%s)", uri);
		break;
			    }
	case EFIDP_MSG_UFS:
		off += format(buf, size, off, "UFS(%d,0x%02x)",
			      dp->ufs.target_id, dp->ufs.lun);
		break;
	case EFIDP_MSG_SD:
		off += format(buf, size, off, "SD(%d)", dp->sd.slot_number);
		break;
	default:
		off += format(buf, size, off, "Msg(%d,", dp->subtype);
		off += format_hex(buf, size, off, (uint8_t *)dp+4,
				  efidp_node_size(dp)-4);
		off += format(buf,size,off,")");
		break;
	}
	return off;
}
Exemplo n.º 18
0
static void unroll_tree(pTHX_ struct sljit_compiler* compiler, HV* seenops,
                        OP* op, OP* end)
{
    // XXX: This basically is the algorithm from walk_exec in B::Concise, but I
    // think it could be done better. (Maybe core will get something like
    // codegen?).

    while (op && op != end) {

        const char* op_hex = format_hex(op);

        // Have we visited this op already?
        if (hv_exists(seenops, op_hex, strlen(op_hex))) {
            DEBUGf(("  ;; Already seen %s [0x%s]\n", OP_NAME(op), op_hex));
            // Insert jump to it
            emit_jump(compiler, op);
            // We know we have followed all the next pointers for this chain,
            // so:
            break;
        }

        // Seen op
        hv_store(seenops, op_hex, 0, &PL_sv_yes, strlen(op_hex));

        if (op->op_type == OP_CUSTOM) {
            // All bets are off
            sljit_emit_return(compiler, SLJIT_MEM, (sljit_w) &PL_op);
        }

        else if (OP_CLASS(op) == OA_LOGOP) {
            unroll_branching_op(compiler, seenops, op, op->op_next,
                                cLOGOPx(op)->op_other);
        }

        else if (op->op_type == OP_SUBST
                 && cPMOPx(op)->op_pmstashstartu.op_pmreplstart) {
            unroll_branching_op(compiler, seenops, op, op->op_next,
                                cPMOPx(op)->op_pmstashstartu.op_pmreplstart);
        }

        else if (op->op_type == OP_GREPSTART || op->op_type == OP_MAPSTART) {
            unroll_branching_op(compiler, seenops, op, op->op_next->op_next,
                                cLOGOPx(op->op_next)->op_other);
        }

        else if (op->op_type == OP_NEXT || op->op_type == OP_LAST
                 || op->op_type == OP_REDO) {
            sljit_emit_return(compiler, SLJIT_MEM, (sljit_w) &PL_op);
            //need_patch = 1; XXX
        }

        else if (op->op_type == OP_FLIP || op->op_type == OP_GOTO) {
            sljit_emit_return(compiler, SLJIT_MEM, (sljit_w) &PL_op);
            //need_patch = 1; XXX
        }

        else if (op->op_type == OP_ENTERSUB) {
            sljit_emit_return(compiler, SLJIT_MEM, (sljit_w) &PL_op);
            //need_patch = 1; XXX
        }

        else if (op->op_type == OP_RETURN || op->op_type == OP_LEAVESUB
                 || op->op_type == OP_REQUIRE) {
            // XXX: leavesublv?
            unroll_op(compiler, op);
            sljit_emit_return(compiler, SLJIT_MEM, (sljit_w) &PL_op);
        }

        else {
            unroll_op(compiler, op);
#ifdef DEBUG
            // Ensure returned OP is actually the one we expect
            struct sljit_jump *jump1 = sljit_emit_cmp(compiler, SLJIT_C_EQUAL,
                                       SLJIT_RETURN_REG, 0, SLJIT_IMM, (sljit_w) op->op_next);
            sljit_emit_op0(compiler, SLJIT_BREAKPOINT);
            sljit_set_label(jump1, sljit_emit_label(compiler));
#endif
        }
        op = op->op_next;
    }
}
Exemplo n.º 19
0
static bool
tls_crypt_v2_unwrap_client_key(struct key2 *client_key, struct buffer *metadata,
                               struct buffer wrapped_client_key,
                               struct key_ctx *server_key)
{
    const char *error_prefix = __func__;
    bool ret = false;
    struct gc_arena gc = gc_new();
    /* The crypto API requires one extra cipher block of buffer head room when
     * decrypting, which nicely matches the tag size of WKc.  So
     * TLS_CRYPT_V2_MAX_WKC_LEN is always large enough for the plaintext. */
    uint8_t plaintext_buf_data[TLS_CRYPT_V2_MAX_WKC_LEN] = { 0 };
    struct buffer plaintext = { 0 };

    dmsg(D_TLS_DEBUG_MED, "%s: unwrapping client key (len=%d): %s", __func__,
         BLEN(&wrapped_client_key), format_hex(BPTR(&wrapped_client_key),
                                               BLEN(&wrapped_client_key),
                                               0, &gc));

    if (TLS_CRYPT_V2_MAX_WKC_LEN < BLEN(&wrapped_client_key))
    {
        CRYPT_ERROR("wrapped client key too big");
    }

    /* Decrypt client key and metadata */
    uint16_t net_len = 0;
    const uint8_t *tag = BPTR(&wrapped_client_key);

    if (BLEN(&wrapped_client_key) < sizeof(net_len))
    {
        CRYPT_ERROR("failed to read length");
    }
    memcpy(&net_len, BEND(&wrapped_client_key) - sizeof(net_len),
           sizeof(net_len));

    if (ntohs(net_len) != BLEN(&wrapped_client_key))
    {
        dmsg(D_TLS_DEBUG_LOW, "%s: net_len=%u, BLEN=%i", __func__,
             ntohs(net_len), BLEN(&wrapped_client_key));
        CRYPT_ERROR("invalid length");
    }

    buf_inc_len(&wrapped_client_key, -(int)sizeof(net_len));

    if (!buf_advance(&wrapped_client_key, TLS_CRYPT_TAG_SIZE))
    {
        CRYPT_ERROR("failed to read tag");
    }

    if (!cipher_ctx_reset(server_key->cipher, tag))
    {
        CRYPT_ERROR("failed to initialize IV");
    }
    buf_set_write(&plaintext, plaintext_buf_data, sizeof(plaintext_buf_data));
    int outlen = 0;
    if (!cipher_ctx_update(server_key->cipher, BPTR(&plaintext), &outlen,
                           BPTR(&wrapped_client_key),
                           BLEN(&wrapped_client_key)))
    {
        CRYPT_ERROR("could not decrypt client key");
    }
    ASSERT(buf_inc_len(&plaintext, outlen));

    if (!cipher_ctx_final(server_key->cipher, BEND(&plaintext), &outlen))
    {
        CRYPT_ERROR("cipher final failed");
    }
    ASSERT(buf_inc_len(&plaintext, outlen));

    /* Check authentication */
    uint8_t tag_check[TLS_CRYPT_TAG_SIZE] = { 0 };
    hmac_ctx_reset(server_key->hmac);
    hmac_ctx_update(server_key->hmac, (void *)&net_len, sizeof(net_len));
    hmac_ctx_update(server_key->hmac, BPTR(&plaintext),
                    BLEN(&plaintext));
    hmac_ctx_final(server_key->hmac, tag_check);

    if (memcmp_constant_time(tag, tag_check, sizeof(tag_check)))
    {
        dmsg(D_CRYPTO_DEBUG, "tag      : %s",
             format_hex(tag, sizeof(tag_check), 0, &gc));
        dmsg(D_CRYPTO_DEBUG, "tag_check: %s",
             format_hex(tag_check, sizeof(tag_check), 0, &gc));
        CRYPT_ERROR("client key authentication error");
    }

    if (buf_len(&plaintext) < sizeof(client_key->keys))
    {
        CRYPT_ERROR("failed to read client key");
    }
    memcpy(&client_key->keys, BPTR(&plaintext), sizeof(client_key->keys));
    ASSERT(buf_advance(&plaintext, sizeof(client_key->keys)));

    if (!buf_copy(metadata, &plaintext))
    {
        CRYPT_ERROR("metadata too large for supplied buffer");
    }

    ret = true;
error_exit:
    if (!ret)
    {
        secure_memzero(client_key, sizeof(*client_key));
    }
    buf_clear(&plaintext);
    gc_free(&gc);
    return ret;
}
Exemplo n.º 20
0
bool
establish_http_proxy_passthru (struct http_proxy_info *p,
			       socket_descriptor_t sd, /* already open to proxy */
			       const char *host,       /* openvpn server remote */
			       const int port,         /* openvpn server port */
			       struct buffer *lookahead,
			       volatile int *signal_received)
{
  struct gc_arena gc = gc_new ();
  char buf[512];
  char buf2[128];
  char get[80];
  int status;
  int nparms;
  bool ret = false;
  bool processed = false;

  /* get user/pass if not previously given */
  if (p->auth_method == HTTP_AUTH_BASIC
      || p->auth_method == HTTP_AUTH_DIGEST
      || p->auth_method == HTTP_AUTH_NTLM)
    get_user_pass_http (p, false);

  /* are we being called again after getting the digest server nonce in the previous transaction? */
  if (p->auth_method == HTTP_AUTH_DIGEST && p->proxy_authenticate)
    {
      nparms = 1;
      status = 407;
    }
  else
    {
      /* format HTTP CONNECT message */
      openvpn_snprintf (buf, sizeof(buf), "CONNECT %s:%d HTTP/%s",
			host,
			port,
			p->options.http_version);

      msg (D_PROXY, "Send to HTTP proxy: '%s'", buf);

      /* send HTTP CONNECT message to proxy */
      if (!send_line_crlf (sd, buf))
	goto error;

      openvpn_snprintf(buf, sizeof(buf), "Host: %s", host);
      if (!send_line_crlf(sd, buf))
        goto error;

      /* send User-Agent string if provided */
      if (p->options.user_agent)
	{
	  openvpn_snprintf (buf, sizeof(buf), "User-Agent: %s",
			    p->options.user_agent);
	  if (!send_line_crlf (sd, buf))
	    goto error;
	}

      /* auth specified? */
      switch (p->auth_method)
	{
	case HTTP_AUTH_NONE:
	  break;

	case HTTP_AUTH_BASIC:
	  openvpn_snprintf (buf, sizeof(buf), "Proxy-Authorization: Basic %s",
			    username_password_as_base64 (p, &gc));
	  msg (D_PROXY, "Attempting Basic Proxy-Authorization");
	  dmsg (D_SHOW_KEYS, "Send to HTTP proxy: '%s'", buf);
	  if (!send_line_crlf (sd, buf))
	    goto error;
	  break;

#if NTLM
	case HTTP_AUTH_NTLM:
	case HTTP_AUTH_NTLM2:
	  /* keep-alive connection */
	  openvpn_snprintf (buf, sizeof(buf), "Proxy-Connection: Keep-Alive");
	  if (!send_line_crlf (sd, buf))
	    goto error;

	  openvpn_snprintf (buf, sizeof(buf), "Proxy-Authorization: NTLM %s",
			    ntlm_phase_1 (p, &gc));
	  msg (D_PROXY, "Attempting NTLM Proxy-Authorization phase 1");
	  dmsg (D_SHOW_KEYS, "Send to HTTP proxy: '%s'", buf);
	  if (!send_line_crlf (sd, buf))
	    goto error;
	  break;
#endif

	default:
	  ASSERT (0);
	}

      /* send empty CR, LF */
      if (!send_crlf (sd))
	goto error;

      /* receive reply from proxy */
      if (!recv_line (sd, buf, sizeof(buf), p->options.timeout, true, NULL, signal_received))
	goto error;

      /* remove trailing CR, LF */
      chomp (buf);

      msg (D_PROXY, "HTTP proxy returned: '%s'", buf);

      /* parse return string */
      nparms = sscanf (buf, "%*s %d", &status);

    }

  /* check for a "407 Proxy Authentication Required" response */
  while (nparms >= 1 && status == 407)
    {
      msg (D_PROXY, "Proxy requires authentication");

      if (p->auth_method == HTTP_AUTH_BASIC && !processed)
	{
	  processed = true;
	}
      else if ((p->auth_method == HTTP_AUTH_NTLM || p->auth_method == HTTP_AUTH_NTLM2) && !processed) /* check for NTLM */
        {
#if NTLM
          /* look for the phase 2 response */

          while (true)
            {
              if (!recv_line (sd, buf, sizeof(buf), p->options.timeout, true, NULL, signal_received))
                goto error;
              chomp (buf);
              msg (D_PROXY, "HTTP proxy returned: '%s'", buf);

              openvpn_snprintf (get, sizeof get, "%%*s NTLM %%%ds", (int) sizeof (buf2) - 1);
              nparms = sscanf (buf, get, buf2);
              buf2[127] = 0; /* we only need the beginning - ensure it's null terminated. */

              /* check for "Proxy-Authenticate: NTLM TlRM..." */
              if (nparms == 1)
                {
                  /* parse buf2 */
                  msg (D_PROXY, "auth string: '%s'", buf2);
                  break;
                }
            }
          /* if we are here then auth string was got */
          msg (D_PROXY, "Received NTLM Proxy-Authorization phase 2 response");

          /* receive and discard everything else */
          while (recv_line (sd, NULL, 0, 2, true, NULL, signal_received))
            ;

          /* now send the phase 3 reply */

          /* format HTTP CONNECT message */
          openvpn_snprintf (buf, sizeof(buf), "CONNECT %s:%d HTTP/%s",
			    host,
			    port,
			    p->options.http_version);

          msg (D_PROXY, "Send to HTTP proxy: '%s'", buf);

          /* send HTTP CONNECT message to proxy */
          if (!send_line_crlf (sd, buf))
            goto error;

          /* keep-alive connection */
          openvpn_snprintf (buf, sizeof(buf), "Proxy-Connection: Keep-Alive");
          if (!send_line_crlf (sd, buf))
            goto error;

          
          /* send HOST etc, */
          openvpn_snprintf (buf, sizeof(buf), "Host: %s", host);
          msg (D_PROXY, "Send to HTTP proxy: '%s'", buf);
          if (!send_line_crlf (sd, buf))
            goto error;

          msg (D_PROXY, "Attempting NTLM Proxy-Authorization phase 3");
	  {
	    const char *np3 = ntlm_phase_3 (p, buf2, &gc);
	    if (!np3)
	      {
		msg (D_PROXY, "NTLM Proxy-Authorization phase 3 failed: received corrupted data from proxy server");
		goto error;
	      }
	    openvpn_snprintf (buf, sizeof(buf), "Proxy-Authorization: NTLM %s", np3);
	  }

          msg (D_PROXY, "Send to HTTP proxy: '%s'", buf);
          if (!send_line_crlf (sd, buf))
	    goto error;
          /* ok so far... */
          /* send empty CR, LF */
          if (!send_crlf (sd))
            goto error;

          /* receive reply from proxy */
          if (!recv_line (sd, buf, sizeof(buf), p->options.timeout, true, NULL, signal_received))
            goto error;

          /* remove trailing CR, LF */
          chomp (buf);

          msg (D_PROXY, "HTTP proxy returned: '%s'", buf);

          /* parse return string */
          nparms = sscanf (buf, "%*s %d", &status);
	  processed = true;
#endif
	}
#if PROXY_DIGEST_AUTH
      else if (p->auth_method == HTTP_AUTH_DIGEST && !processed)
	{
	  char *pa = p->proxy_authenticate;
	  const int method = p->auth_method;
	  ASSERT(pa);

	  if (method == HTTP_AUTH_DIGEST)
	    {
	      const char *http_method = "CONNECT";
	      const char *nonce_count = "00000001";
	      const char *qop = "auth";
	      const char *username = p->up.username;
	      const char *password = p->up.password;
	      char *opaque_kv = "";
	      char uri[128];
	      uint8_t cnonce_raw[8];
	      uint8_t *cnonce;
	      HASHHEX session_key;
	      HASHHEX response;

	      const char *realm = get_pa_var("realm", pa, &gc);
	      const char *nonce = get_pa_var("nonce", pa, &gc);
	      const char *algor = get_pa_var("algorithm", pa, &gc);
	      const char *opaque = get_pa_var("opaque", pa, &gc);

	      /* generate a client nonce */
	      ASSERT(rand_bytes(cnonce_raw, sizeof(cnonce_raw)));
	      cnonce = make_base64_string2(cnonce_raw, sizeof(cnonce_raw), &gc);


	      /* build the digest response */
	      openvpn_snprintf (uri, sizeof(uri), "%s:%d",
				host,
				port);

	      if (opaque)
		{
		  const int len = strlen(opaque)+16;
		  opaque_kv = gc_malloc(len, false, &gc);
		  openvpn_snprintf (opaque_kv, len, ", opaque=\"%s\"", opaque);
		}

	      DigestCalcHA1(algor,
			    username,
			    realm,
			    password,
			    nonce,
			    (char *)cnonce,
			    session_key);
	      DigestCalcResponse(session_key,
				 nonce,
				 nonce_count,
				 (char *)cnonce,
				 qop,
				 http_method,
				 uri,
				 NULL,
				 response);

	      /* format HTTP CONNECT message */
	      openvpn_snprintf (buf, sizeof(buf), "%s %s HTTP/%s",
				http_method,
				uri,
				p->options.http_version);

	      msg (D_PROXY, "Send to HTTP proxy: '%s'", buf);

	      /* send HTTP CONNECT message to proxy */
	      if (!send_line_crlf (sd, buf))
		goto error;

	      /* send HOST etc, */
	      openvpn_snprintf (buf, sizeof(buf), "Host: %s", host);
	      msg (D_PROXY, "Send to HTTP proxy: '%s'", buf);
	      if (!send_line_crlf (sd, buf))
		goto error;

	      /* send digest response */
	      openvpn_snprintf (buf, sizeof(buf), "Proxy-Authorization: Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", qop=%s, nc=%s, cnonce=\"%s\", response=\"%s\"%s",
				username,
				realm,
				nonce,
				uri,
				qop,
				nonce_count,
				cnonce,
				response,
				opaque_kv
				);
	      msg (D_PROXY, "Send to HTTP proxy: '%s'", buf);
	      if (!send_line_crlf (sd, buf))
		goto error;
	      if (!send_crlf (sd))
		goto error;

	      /* receive reply from proxy */
	      if (!recv_line (sd, buf, sizeof(buf), p->options.timeout, true, NULL, signal_received))
		goto error;

	      /* remove trailing CR, LF */
	      chomp (buf);

	      msg (D_PROXY, "HTTP proxy returned: '%s'", buf);

	      /* parse return string */
	      nparms = sscanf (buf, "%*s %d", &status);
	      processed = true;
	    }
	  else
	    {
	      msg (D_PROXY, "HTTP proxy: digest method not supported");
	      goto error;
	    }
	}
#endif
      else if (p->options.auth_retry)
	{
	  /* figure out what kind of authentication the proxy needs */
	  char *pa = NULL;
	  const int method = get_proxy_authenticate(sd,
						    p->options.timeout,
						    &pa,
						    NULL,
						    signal_received);
	  if (method != HTTP_AUTH_NONE)
	    {
	      if (pa)
		msg (D_PROXY, "HTTP proxy authenticate '%s'", pa);
	      if (p->options.auth_retry == PAR_NCT && method == HTTP_AUTH_BASIC)
		{
		  msg (D_PROXY, "HTTP proxy: support for basic auth and other cleartext proxy auth methods is disabled");
		  goto error;
		}
	      p->auth_method = method;
	      store_proxy_authenticate(p, pa);
	      ret = true;
	      goto done;
	    }
	  else
	    {
	      msg (D_PROXY, "HTTP proxy: do not recognize the authentication method required by proxy");
	      free (pa);
	      goto error;
	    }
	}
      else
	{
	  if (!processed)
	    msg (D_PROXY, "HTTP proxy: no support for proxy authentication method");
	  goto error;
	}

      /* clear state */
      if (p->options.auth_retry)
	clear_user_pass_http();
      store_proxy_authenticate(p, NULL);
    }

  /* check return code, success = 200 */
  if (nparms < 1 || status != 200)
    {
      msg (D_LINK_ERRORS, "HTTP proxy returned bad status");
#if 0
      /* DEBUGGING -- show a multi-line HTTP error response */
      dump_residual(sd, p->options.timeout, signal_received);
#endif
      goto error;
    }

  /* SUCCESS */

  /* receive line from proxy and discard */
  if (!recv_line (sd, NULL, 0, p->options.timeout, true, NULL, signal_received))
    goto error;

  /*
   * Toss out any extraneous chars, but don't throw away the
   * start of the OpenVPN data stream (put it in lookahead).
   */
  while (recv_line (sd, NULL, 0, 2, false, lookahead, signal_received))
    ;

  /* reset queried_creds so that we don't think that the next creds request is due to an auth error */
  p->queried_creds = false;

#if 0
  if (lookahead && BLEN (lookahead))
    msg (M_INFO, "HTTP PROXY: lookahead: %s", format_hex (BPTR (lookahead), BLEN (lookahead), 0));
#endif

 done:
  gc_free (&gc);
  return ret;

 error:
  /* on error, should we exit or restart? */
  if (!*signal_received)
    *signal_received = (p->options.retry ? SIGUSR1 : SIGTERM); /* SOFT-SIGUSR1 -- HTTP proxy error */
  gc_free (&gc);
  return ret;
}
Exemplo n.º 21
0
bool
tls_crypt_unwrap(const struct buffer *src, struct buffer *dst,
                 struct crypto_options *opt)
{
    static const char error_prefix[] = "tls-crypt unwrap error";
    const struct key_ctx *ctx = &opt->key_ctx_bi.decrypt;
    struct gc_arena gc;

    gc_init(&gc);

    ASSERT(opt);
    ASSERT(src->len > 0);
    ASSERT(ctx->cipher);
    ASSERT(packet_id_initialized(&opt->packet_id)
           || (opt->flags & CO_IGNORE_PACKET_ID));

    dmsg(D_PACKET_CONTENT, "TLS-CRYPT UNWRAP FROM: %s",
         format_hex(BPTR(src), BLEN(src), 80, &gc));

    if (buf_len(src) < TLS_CRYPT_OFF_CT)
    {
        CRYPT_ERROR("packet too short");
    }

    /* Decrypt cipher text */
    {
        int outlen = 0;

        /* Buffer overflow check (should never fail) */
        if (!buf_safe(dst, BLEN(src) - TLS_CRYPT_OFF_CT + TLS_CRYPT_BLOCK_SIZE))
        {
            CRYPT_ERROR("potential buffer overflow");
        }

        if (!cipher_ctx_reset(ctx->cipher, BPTR(src) + TLS_CRYPT_OFF_TAG))
        {
            CRYPT_ERROR("cipher reset failed");
        }
        if (!cipher_ctx_update(ctx->cipher, BPTR(dst), &outlen,
                               BPTR(src) + TLS_CRYPT_OFF_CT, BLEN(src) - TLS_CRYPT_OFF_CT))
        {
            CRYPT_ERROR("cipher update failed");
        }
        ASSERT(buf_inc_len(dst, outlen));
        if (!cipher_ctx_final(ctx->cipher, BPTR(dst), &outlen))
        {
            CRYPT_ERROR("cipher final failed");
        }
        ASSERT(buf_inc_len(dst, outlen));
    }

    /* Check authentication */
    {
        const uint8_t *tag = BPTR(src) + TLS_CRYPT_OFF_TAG;
        uint8_t tag_check[TLS_CRYPT_TAG_SIZE] = { 0 };

        dmsg(D_PACKET_CONTENT, "TLS-CRYPT UNWRAP AD: %s",
             format_hex(BPTR(src), TLS_CRYPT_OFF_TAG, 0, &gc));
        dmsg(D_PACKET_CONTENT, "TLS-CRYPT UNWRAP TO: %s",
             format_hex(BPTR(dst), BLEN(dst), 80, &gc));

        hmac_ctx_reset(ctx->hmac);
        hmac_ctx_update(ctx->hmac, BPTR(src), TLS_CRYPT_OFF_TAG);
        hmac_ctx_update(ctx->hmac, BPTR(dst), BLEN(dst));
        hmac_ctx_final(ctx->hmac, tag_check);

        if (memcmp_constant_time(tag, tag_check, sizeof(tag_check)))
        {
            dmsg(D_CRYPTO_DEBUG, "tag      : %s",
                 format_hex(tag, sizeof(tag_check), 0, &gc));
            dmsg(D_CRYPTO_DEBUG, "tag_check: %s",
                 format_hex(tag_check, sizeof(tag_check), 0, &gc));
            CRYPT_ERROR("packet authentication failed");
        }
    }

    /* Check replay */
    if (!(opt->flags & CO_IGNORE_PACKET_ID))
    {
        struct packet_id_net pin;
        struct buffer tmp = *src;
        ASSERT(buf_advance(&tmp, TLS_CRYPT_OFF_PID));
        ASSERT(packet_id_read(&pin, &tmp, true));
        if (!crypto_check_replay(opt, &pin, error_prefix, &gc))
        {
            CRYPT_ERROR("packet replay");
        }
    }

    gc_free(&gc);
    return true;

error_exit:
    crypto_clear_error();
    dst->len = 0;
    gc_free(&gc);
    return false;
}
Exemplo n.º 22
0
bool
tls_crypt_wrap(const struct buffer *src, struct buffer *dst,
               struct crypto_options *opt)
{
    const struct key_ctx *ctx = &opt->key_ctx_bi.encrypt;
    struct gc_arena gc;

    /* IV, packet-ID and implicit IV required for this mode. */
    ASSERT(ctx->cipher);
    ASSERT(ctx->hmac);
    ASSERT(packet_id_initialized(&opt->packet_id));
    ASSERT(hmac_ctx_size(ctx->hmac) == 256/8);

    gc_init(&gc);

    dmsg(D_PACKET_CONTENT, "TLS-CRYPT WRAP FROM: %s",
         format_hex(BPTR(src), BLEN(src), 80, &gc));

    /* Get packet ID */
    if (!packet_id_write(&opt->packet_id.send, dst, true, false))
    {
        msg(D_CRYPT_ERRORS, "TLS-CRYPT ERROR: packet ID roll over.");
        goto err;
    }

    dmsg(D_PACKET_CONTENT, "TLS-CRYPT WRAP AD: %s",
         format_hex(BPTR(dst), BLEN(dst), 0, &gc));

    /* Buffer overflow check */
    if (!buf_safe(dst, BLEN(src) + TLS_CRYPT_BLOCK_SIZE + TLS_CRYPT_TAG_SIZE))
    {
        msg(D_CRYPT_ERRORS, "TLS-CRYPT WRAP: buffer size error, "
            "sc=%d so=%d sl=%d dc=%d do=%d dl=%d", src->capacity, src->offset,
            src->len, dst->capacity, dst->offset, dst->len);
        goto err;
    }

    /* Calculate auth tag and synthetic IV */
    {
        uint8_t *tag = NULL;
        hmac_ctx_reset(ctx->hmac);
        hmac_ctx_update(ctx->hmac, BPTR(dst), BLEN(dst));
        hmac_ctx_update(ctx->hmac, BPTR(src), BLEN(src));

        ASSERT(tag = buf_write_alloc(dst, TLS_CRYPT_TAG_SIZE));
        hmac_ctx_final(ctx->hmac, tag);

        dmsg(D_PACKET_CONTENT, "TLS-CRYPT WRAP TAG: %s",
             format_hex(tag, TLS_CRYPT_TAG_SIZE, 0, &gc));

        /* Use the 128 most significant bits of the tag as IV */
        ASSERT(cipher_ctx_reset(ctx->cipher, tag));
    }

    /* Encrypt src */
    {
        int outlen = 0;
        ASSERT(cipher_ctx_update(ctx->cipher, BEND(dst), &outlen,
                                 BPTR(src), BLEN(src)));
        ASSERT(buf_inc_len(dst, outlen));
        ASSERT(cipher_ctx_final(ctx->cipher, BPTR(dst), &outlen));
        ASSERT(buf_inc_len(dst, outlen));
    }

    dmsg(D_PACKET_CONTENT, "TLS-CRYPT WRAP TO: %s",
         format_hex(BPTR(dst), BLEN(dst), 80, &gc));

    gc_free(&gc);
    return true;

err:
    crypto_clear_error();
    dst->len = 0;
    gc_free(&gc);
    return false;
}
Exemplo n.º 23
0
const char *
session_id_print (const struct session_id *sid, struct gc_arena *gc)
{
  return format_hex (sid->id, SID_SIZE, 0, gc);
}
Exemplo n.º 24
0
/*
 * If (opt->flags & CO_USE_IV) is not NULL, we will read an IV from the packet.
 *
 * Set buf->len to 0 and return false on decrypt error.
 *
 * On success, buf is set to point to plaintext, true
 * is returned.
 */
bool
openvpn_decrypt (struct buffer *buf, struct buffer work,
		 const struct crypto_options *opt,
		 const struct frame* frame)
{
  static const char error_prefix[] = "Authenticate/Decrypt packet error";
  struct gc_arena gc;
  gc_init (&gc);

  if (buf->len > 0 && opt->key_ctx_bi)
    {
      struct key_ctx *ctx = &opt->key_ctx_bi->decrypt;
      struct packet_id_net pin;
      bool have_pin = false;

      /* Verify the HMAC */
      if (ctx->hmac)
	{
	  int hmac_len;
	  uint8_t local_hmac[MAX_HMAC_KEY_LENGTH]; /* HMAC of ciphertext computed locally */

	  hmac_ctx_reset(ctx->hmac);

	  /* Assume the length of the input HMAC */
	  hmac_len = hmac_ctx_size (ctx->hmac);

	  /* Authentication fails if insufficient data in packet for HMAC */
	  if (buf->len < hmac_len)
	    CRYPT_ERROR ("missing authentication info");

	  hmac_ctx_update (ctx->hmac, BPTR (buf) + hmac_len, BLEN (buf) - hmac_len);
	  hmac_ctx_final (ctx->hmac, local_hmac);

	  /* Compare locally computed HMAC with packet HMAC */
	  if (memcmp_constant_time (local_hmac, BPTR (buf), hmac_len))
	    CRYPT_ERROR ("packet HMAC authentication failed");

	  ASSERT (buf_advance (buf, hmac_len));
	}

      /* Decrypt packet ID + payload */

      if (ctx->cipher)
	{
	  const int iv_size = cipher_ctx_iv_length (ctx->cipher);
	  const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt (ctx->cipher);
	  uint8_t iv_buf[OPENVPN_MAX_IV_LENGTH];
	  int outlen;

	  /* initialize work buffer with FRAME_HEADROOM bytes of prepend capacity */
	  ASSERT (buf_init (&work, FRAME_HEADROOM_ADJ (frame, FRAME_HEADROOM_MARKER_DECRYPT)));

	  /* use IV if user requested it */
	  CLEAR (iv_buf);
	  if (opt->flags & CO_USE_IV)
	    {
	      if (buf->len < iv_size)
		CRYPT_ERROR ("missing IV info");
	      memcpy (iv_buf, BPTR (buf), iv_size);
	      ASSERT (buf_advance (buf, iv_size));
	    }

	  /* show the IV's initial state */
	  if (opt->flags & CO_USE_IV)
	    dmsg (D_PACKET_CONTENT, "DECRYPT IV: %s", format_hex (iv_buf, iv_size, 0, &gc));

	  if (buf->len < 1)
	    CRYPT_ERROR ("missing payload");

	  /* ctx->cipher was already initialized with key & keylen */
	  if (!cipher_ctx_reset (ctx->cipher, iv_buf))
	    CRYPT_ERROR ("cipher init failed");

	  /* Buffer overflow check (should never happen) */
	  if (!buf_safe (&work, buf->len + cipher_ctx_block_size(ctx->cipher)))
	    CRYPT_ERROR ("potential buffer overflow");

	  /* Decrypt packet ID, payload */
	  if (!cipher_ctx_update (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf)))
	    CRYPT_ERROR ("cipher update failed");
	  ASSERT (buf_inc_len(&work, outlen));

	  /* Flush the decryption buffer */
	  if (!cipher_ctx_final (ctx->cipher, BPTR (&work) + outlen, &outlen))
	    CRYPT_ERROR ("cipher final failed");
	  ASSERT (buf_inc_len(&work, outlen));

	  dmsg (D_PACKET_CONTENT, "DECRYPT TO: %s",
	       format_hex (BPTR (&work), BLEN (&work), 80, &gc));

	  /* Get packet ID from plaintext buffer or IV, depending on cipher mode */
	  {
	    if (cipher_kt_mode_cbc(cipher_kt))
	      {
		if (opt->packet_id)
		  {
		    if (!packet_id_read (&pin, &work, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM)))
		      CRYPT_ERROR ("error reading CBC packet-id");
		    have_pin = true;
		  }
	      }
	    else if (cipher_kt_mode_ofb_cfb(cipher_kt))
	      {
		struct buffer b;

		ASSERT (opt->flags & CO_USE_IV);    /* IV and packet-ID required */
		ASSERT (opt->packet_id); /*  for this mode. */

		buf_set_read (&b, iv_buf, iv_size);
		if (!packet_id_read (&pin, &b, true))
		  CRYPT_ERROR ("error reading CFB/OFB packet-id");
		have_pin = true;
	      }
	    else /* We only support CBC, CFB, or OFB modes right now */
	      {
		ASSERT (0);
	      }
	  }
	}
      else
	{
	  work = *buf;
	  if (opt->packet_id)
	    {
	      if (!packet_id_read (&pin, &work, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM)))
		CRYPT_ERROR ("error reading packet-id");
	      have_pin = !BOOL_CAST (opt->flags & CO_IGNORE_PACKET_ID);
	    }
	}
      
      if (have_pin)
	{
	  packet_id_reap_test (&opt->packet_id->rec);
	  if (packet_id_test (&opt->packet_id->rec, &pin))
	    {
	      packet_id_add (&opt->packet_id->rec, &pin);
	      if (opt->pid_persist && (opt->flags & CO_PACKET_ID_LONG_FORM))
		packet_id_persist_save_obj (opt->pid_persist, opt->packet_id);
	    }
	  else
	    {
	      if (!(opt->flags & CO_MUTE_REPLAY_WARNINGS))
	      msg (D_REPLAY_ERRORS, "%s: bad packet ID (may be a replay): %s -- see the man page entry for --no-replay and --replay-window for more info or silence this warning with --mute-replay-warnings",
		   error_prefix, packet_id_net_print (&pin, true, &gc));
	      goto error_exit;
	    }
	}
      *buf = work;
    }

  gc_free (&gc);
  return true;

 error_exit:
  crypto_clear_error();
  buf->len = 0;
  gc_free (&gc);
  return false;
}
Exemplo n.º 25
0
bool
establish_http_proxy_passthru (struct http_proxy_info *p,
			       socket_descriptor_t sd, /* already open to proxy */
			       const char *host,       /* openvpn server remote */
			       const int port,         /* openvpn server port */
			       struct buffer *lookahead,
			       volatile int *signal_received)
{
  struct gc_arena gc = gc_new ();
  char buf[256];
  char buf2[128];
  char get[80];
  int status;
  int nparms;
  bool ret = false;

  /* get user/pass if not previously given or if --auto-proxy is being used */
  if (p->auth_method == HTTP_AUTH_BASIC
      || p->auth_method == HTTP_AUTH_NTLM)
    get_user_pass_http (p, false);

  /* format HTTP CONNECT message */
  openvpn_snprintf (buf, sizeof(buf), "CONNECT %s:%d HTTP/%s\r\nHOST: %s:%d",
		    host,
		    port,
		    p->options.http_version,
		    host,
		    port);

  msg (D_PROXY, "Send to HTTP proxy: '%s'", buf);

  /* send HTTP CONNECT message to proxy */
  if (!send_line_crlf (sd, buf))
    goto error;

  /* send User-Agent string if provided */
  if (p->options.user_agent)
    {
      openvpn_snprintf (buf, sizeof(buf), "User-Agent: %s",
			p->options.user_agent);
      if (!send_line_crlf (sd, buf))
	goto error;
    }

  /* auth specified? */
  switch (p->auth_method)
    {
    case HTTP_AUTH_NONE:
      break;

    case HTTP_AUTH_BASIC:
      openvpn_snprintf (buf, sizeof(buf), "Proxy-Authorization: Basic %s",
			username_password_as_base64 (p, &gc));
      msg (D_PROXY, "Attempting Basic Proxy-Authorization");
      dmsg (D_SHOW_KEYS, "Send to HTTP proxy: '%s'", buf);
      openvpn_sleep (1);
      if (!send_line_crlf (sd, buf))
	goto error;
      break;

#if NTLM
    case HTTP_AUTH_NTLM:
    case HTTP_AUTH_NTLM2:
      /* keep-alive connection */
      openvpn_snprintf (buf, sizeof(buf), "Proxy-Connection: Keep-Alive");
      if (!send_line_crlf (sd, buf))
	goto error;

      openvpn_snprintf (buf, sizeof(buf), "Proxy-Authorization: NTLM %s",
			ntlm_phase_1 (p, &gc));
      msg (D_PROXY, "Attempting NTLM Proxy-Authorization phase 1");
      dmsg (D_SHOW_KEYS, "Send to HTTP proxy: '%s'", buf);
      openvpn_sleep (1);
      if (!send_line_crlf (sd, buf))
	goto error;
      break;
#endif

    default:
      ASSERT (0);
    }

  /* send empty CR, LF */
  openvpn_sleep (1);
  if (!send_crlf (sd))
    goto error;

  /* receive reply from proxy */
  if (!recv_line (sd, buf, sizeof(buf), p->options.timeout, true, NULL, signal_received))
    goto error;

  /* remove trailing CR, LF */
  chomp (buf);

  msg (D_PROXY, "HTTP proxy returned: '%s'", buf);

  /* parse return string */
  nparms = sscanf (buf, "%*s %d", &status);

  /* check for a "407 Proxy Authentication Required" response */
  if (nparms >= 1 && status == 407)
    {
      msg (D_PROXY, "Proxy requires authentication");

      /* check for NTLM */
      if (p->auth_method == HTTP_AUTH_NTLM || p->auth_method == HTTP_AUTH_NTLM2)
        {
#if NTLM
          /* look for the phase 2 response */

          while (true)
            {
              if (!recv_line (sd, buf, sizeof(buf), p->options.timeout, true, NULL, signal_received))
                goto error;
              chomp (buf);
              msg (D_PROXY, "HTTP proxy returned: '%s'", buf);

              openvpn_snprintf (get, sizeof get, "%%*s NTLM %%%ds", (int) sizeof (buf2) - 1);
              nparms = sscanf (buf, get, buf2);
              buf2[127] = 0; /* we only need the beginning - ensure it's null terminated. */

              /* check for "Proxy-Authenticate: NTLM TlRM..." */
              if (nparms == 1)
                {
                  /* parse buf2 */
                  msg (D_PROXY, "auth string: '%s'", buf2);
                  break;
                }
            }
          /* if we are here then auth string was got */
          msg (D_PROXY, "Received NTLM Proxy-Authorization phase 2 response");

          /* receive and discard everything else */
          while (recv_line (sd, NULL, 0, p->options.timeout, true, NULL, signal_received))
            ;

          /* now send the phase 3 reply */

          /* format HTTP CONNECT message */
          openvpn_snprintf (buf, sizeof(buf), "CONNECT %s:%d HTTP/%s",
			    host,
			    port,
			    p->options.http_version);

          msg (D_PROXY, "Send to HTTP proxy: '%s'", buf);

          /* send HTTP CONNECT message to proxy */
          if (!send_line_crlf (sd, buf))
            goto error;

          /* keep-alive connection */
          openvpn_snprintf (buf, sizeof(buf), "Proxy-Connection: Keep-Alive");
          if (!send_line_crlf (sd, buf))
            goto error;

          
          /* send HOST etc, */
          openvpn_sleep (1);
          openvpn_snprintf (buf, sizeof(buf), "Host: %s", host);
          msg (D_PROXY, "Send to HTTP proxy: '%s'", buf);
          if (!send_line_crlf (sd, buf))
            goto error;

          msg (D_PROXY, "Attempting NTLM Proxy-Authorization phase 3");
	  {
	    const char *np3 = ntlm_phase_3 (p, buf2, &gc);
	    if (!np3)
	      {
		msg (D_PROXY, "NTLM Proxy-Authorization phase 3 failed: received corrupted data from proxy server");
		goto error;
	      }
	    openvpn_snprintf (buf, sizeof(buf), "Proxy-Authorization: NTLM %s", np3);
	  }

          msg (D_PROXY, "Send to HTTP proxy: '%s'", buf);
          openvpn_sleep (1);
          if (!send_line_crlf (sd, buf))
	    goto error;
          /* ok so far... */
          /* send empty CR, LF */
          openvpn_sleep (1);
          if (!send_crlf (sd))
            goto error;

          /* receive reply from proxy */
          if (!recv_line (sd, buf, sizeof(buf), p->options.timeout, true, NULL, signal_received))
            goto error;

          /* remove trailing CR, LF */
          chomp (buf);

          msg (D_PROXY, "HTTP proxy returned: '%s'", buf);

          /* parse return string */
          nparms = sscanf (buf, "%*s %d", &status);
#else
	  ASSERT (0); /* No NTLM support */
#endif
	}
      else if (p->auth_method == HTTP_AUTH_NONE && p->options.auth_retry)
	{
	  /*
	   * Proxy needs authentication, but we don't have a user/pass.
	   * Now we will change p->auth_method and return true so that
	   * our caller knows to call us again on a newly opened socket.
	   * JYFIXME: This code needs to check proxy error output and set
	   * JYFIXME: p->auth_method = HTTP_AUTH_NTLM if necessary.
	   */
	  p->auth_method = HTTP_AUTH_BASIC;
	  ret = true;
	  goto done;
	}
      else
	goto error;
    }


  /* check return code, success = 200 */
  if (nparms < 1 || status != 200)
    {
      msg (D_LINK_ERRORS, "HTTP proxy returned bad status");
#if 0
      /* DEBUGGING -- show a multi-line HTTP error response */
      while (true)
	{
	  if (!recv_line (sd, buf, sizeof (buf), p->options.timeout, true, NULL, signal_received))
	    goto error;
	  chomp (buf);
	  msg (D_PROXY, "HTTP proxy returned: '%s'", buf);
	}
#endif
      goto error;
    }

  /* receive line from proxy and discard */
  if (!recv_line (sd, NULL, 0, p->options.timeout, true, NULL, signal_received))
    goto error;

  /*
   * Toss out any extraneous chars, but don't throw away the
   * start of the OpenVPN data stream (put it in lookahead).
   */
  while (recv_line (sd, NULL, 0, 2, false, lookahead, signal_received))
    ;

#if 0
  if (lookahead && BLEN (lookahead))
    msg (M_INFO, "HTTP PROXY: lookahead: %s", format_hex (BPTR (lookahead), BLEN (lookahead), 0));
#endif

 done:
  gc_free (&gc);
  return ret;

 error:
  /* on error, should we exit or restart? */
  if (!*signal_received)
    *signal_received = (p->options.retry ? SIGUSR1 : SIGTERM); /* SOFT-SIGUSR1 -- HTTP proxy error */
  gc_free (&gc);
  return ret;
}
static int
archive_write_newc_header(struct archive_write *a, struct archive_entry *entry)
{
    struct cpio *cpio;
    const char *p, *path;
    int pathlength, ret;
    struct cpio_header_newc  h;
    int pad;

    cpio = (struct cpio *)a->format_data;
    ret = 0;

    path = archive_entry_pathname(entry);
    pathlength = strlen(path) + 1; /* Include trailing null. */

    memset(&h, 0, sizeof(h));
    format_hex(0x070701, &h.c_magic, sizeof(h.c_magic));
    format_hex(archive_entry_devmajor(entry), &h.c_devmajor, sizeof(h.c_devmajor));
    format_hex(archive_entry_devminor(entry), &h.c_devminor, sizeof(h.c_devminor));
    if (archive_entry_ino64(entry) > 0xffffffff) {
        archive_set_error(&a->archive, ERANGE, "large inode number truncated");
        ret = ARCHIVE_WARN;
    }

    format_hex(archive_entry_ino64(entry) & 0xffffffff, &h.c_ino, sizeof(h.c_ino));
    format_hex(archive_entry_mode(entry), &h.c_mode, sizeof(h.c_mode));
    format_hex(archive_entry_uid(entry), &h.c_uid, sizeof(h.c_uid));
    format_hex(archive_entry_gid(entry), &h.c_gid, sizeof(h.c_gid));
    format_hex(archive_entry_nlink(entry), &h.c_nlink, sizeof(h.c_nlink));
    if (archive_entry_filetype(entry) == AE_IFBLK
        || archive_entry_filetype(entry) == AE_IFCHR) {
        format_hex(archive_entry_rdevmajor(entry), &h.c_rdevmajor, sizeof(h.c_rdevmajor));
        format_hex(archive_entry_rdevminor(entry), &h.c_rdevminor, sizeof(h.c_rdevminor));
    } else {
        format_hex(0, &h.c_rdevmajor, sizeof(h.c_rdevmajor));
        format_hex(0, &h.c_rdevminor, sizeof(h.c_rdevminor));
    }
    format_hex(archive_entry_mtime(entry), &h.c_mtime, sizeof(h.c_mtime));
    format_hex(pathlength, &h.c_namesize, sizeof(h.c_namesize));
    format_hex(0, &h.c_checksum, sizeof(h.c_checksum));

    /* Non-regular files don't store bodies. */
    if (archive_entry_filetype(entry) != AE_IFREG)
        archive_entry_set_size(entry, 0);

    /* Symlinks get the link written as the body of the entry. */
    p = archive_entry_symlink(entry);
    if (p != NULL  &&  *p != '\0')
        format_hex(strlen(p), &h.c_filesize, sizeof(h.c_filesize));
    else
        format_hex(archive_entry_size(entry),
            &h.c_filesize, sizeof(h.c_filesize));

    ret = (a->compressor.write)(a, &h, sizeof(h));
    if (ret != ARCHIVE_OK)
        return (ARCHIVE_FATAL);

    /* Pad pathname to even length. */
    ret = (a->compressor.write)(a, path, pathlength);
    if (ret != ARCHIVE_OK)
        return (ARCHIVE_FATAL);
    pad = PAD4(pathlength + sizeof(struct cpio_header_newc));
    if (pad)
        ret = (a->compressor.write)(a, "\0\0\0", pad);
    if (ret != ARCHIVE_OK)
        return (ARCHIVE_FATAL);

    cpio->entry_bytes_remaining = archive_entry_size(entry);
    cpio->padding = PAD4(cpio->entry_bytes_remaining);

    /* Write the symlink now. */
    if (p != NULL  &&  *p != '\0') {
        ret = (a->compressor.write)(a, p, strlen(p));
        if (ret != ARCHIVE_OK)
            return (ARCHIVE_FATAL);
        pad = PAD4(strlen(p));
        ret = (a->compressor.write)(a, "\0\0\0", pad);
    }

    return (ret);
}
Exemplo n.º 27
0
int dataman_process_keep_alive(struct netconn *nc, uint8_t *rawmsg, int len)
{
	struct dataman * dm = (struct dataman *)(nc->data);

	uint8_t *msgptr = rawmsg + cw_get_hdr_msg_offset(rawmsg);


	int elems_len = cw_get_datamsg_elems_len(msgptr);
	uint8_t * elems_ptr = cw_get_datamsg_elems_ptr(msgptr);
	uint8_t * elem;

	cw_foreach_elem(elem, elems_ptr, elems_len) {

		if (cw_get_elem_id(elem) == CW_ELEM_SESSION_ID){
			uint8_t sessid[16];
			memset(sessid,0,16);

			int sessid_len = cw_get_elem_len(elem);

			printf("Sess id len = %d\n",sessid_len);

			memcpy(sessid,cw_get_elem_data(elem),sessid_len);

			struct wtpman * wtpman = wtplist_get_by_session_id(sessid);
			if (wtpman){
				if (!dm->wtpman)
					dm->wtpman=wtpman;

				uint8_t buffer[128];
				uint8_t * dl = cw_init_data_keep_alive_msg(buffer,NULL);
				uint8_t * d=dl+2;

				int l = cw_put_elem_session_id(d,sessid,sessid_len);
				cw_put_word(dl,l);

				int total_len = dl-buffer + l+2;
				printf("len len %d\n",l);
				printf("Total len = %d\n",total_len);

				netconn_send_capwap_msg(nc,buffer,total_len);
				return len;
					





				printf("Found!i yes I vae found it\n");
					
			}



			int l = cw_get_elem_len(elem);

			printf("ElemID: %d, len = %d\n", cw_get_elem_id(elem),l);
			char cb[64];
			format_hex(cb,sessid,16);
			printf("Session ID: %s",cb);




		}



	}

	errno=EAGAIN;
	return -1;	
}
Exemplo n.º 28
0
    bool format(const DistributedType* dtype)
    {
        Type type = dtype->get_type();
        switch(type) {
        case T_INVALID: {
            out << "<invalid>";
            break;
        }
        case T_INT8: {
            if(!remaining(sizeof(int8_t))) {
                return false;
            }
            int v = *(int8_t*)(in + offset);
            offset += sizeof(int8_t);
            out << v;
            break;
        }
        case T_INT16: {
            if(!remaining(sizeof(int16_t))) {
                return false;
            }
            int v = swap_le(*(int16_t*)(in + offset));
            offset += sizeof(int16_t);
            out << v;
            break;
        }
        case T_INT32: {
            if(!remaining(sizeof(int32_t))) {
                return false;
            }
            int v = swap_le(*(int32_t*)(in + offset));
            offset += sizeof(int32_t);
            out << v;
            break;
        }
        case T_INT64: {
            if(!remaining(sizeof(int64_t))) {
                return false;
            }
            int64_t v = swap_le(*(int64_t*)(in + offset));
            offset += sizeof(int64_t);
            out << v;
            break;
        }
        case T_UINT8: {
            if(!remaining(sizeof(uint8_t))) {
                return false;
            }
            unsigned int v = *(uint8_t*)(in + offset);
            offset += sizeof(uint8_t);
            out << v;
            break;
        }
        case T_UINT16: {
            if(!remaining(sizeof(uint16_t))) {
                return false;
            }
            unsigned int v = swap_le(*(uint16_t*)(in + offset));
            offset += sizeof(uint16_t);
            out << v;
            break;
        }
        case T_UINT32: {
            if(!remaining(sizeof(uint32_t))) {
                return false;
            }
            unsigned int v = swap_le(*(uint32_t*)(in + offset));
            offset += sizeof(uint32_t);
            out << v;
            break;
        }
        case T_UINT64: {
            if(!remaining(sizeof(uint64_t))) {
                return false;
            }
            uint64_t v = swap_le(*(uint64_t*)(in + offset));
            offset += sizeof(uint64_t);
            out << v;
            break;
        }
        case T_FLOAT32: {
            if(!remaining(sizeof(float))) {
                return false;
            }
            float v = (float)swap_le(*(float*)(in + offset));
            offset += sizeof(float);
            out << v;
            break;
        }
        case T_FLOAT64: {
            if(!remaining(sizeof(double))) {
                return false;
            }
            double v = (double)swap_le(*(double*)(in + offset));
            offset += sizeof(double);
            out << v;
            break;
        }
        case T_CHAR: {
            if(!remaining(sizeof(char))) {
                return false;
            }
            char v = *(char*)(in + offset);
            format_quoted('\'', string(1, v), out);
            offset += sizeof(char);
            break;
        }
        case T_STRING: {
            // Read string length
            sizetag_t length = dtype->get_size();


            // If we have a string alias format as a quoted string
            if(dtype->has_alias() && dtype->get_alias() == "string") {
                // Read string
                if(!remaining(length)) {
                    return false;
                }
                string str((const char*)in + offset, length);
                offset += length;

                // Enquoute and escape string then output
                format_quoted('"', str, out);
            } else {
                // Otherwise format as an array of char
                out << '[';
                const ArrayType* arr = dtype->as_array();
                bool ok = format(arr->get_element_type());
                if(!ok) {
                    return false;
                }
                for(unsigned int i = 1; i < arr->get_array_size(); ++i) {
                    out << ", ";
                    ok = format(arr->get_element_type());
                    if(!ok) {
                        return false;
                    }
                }

                out << ']';
            }
            break;
        }
        case T_VARSTRING: {

            // If we have a string alias format as a quoted string
            if(dtype->has_alias() && dtype->get_alias() == "string") {
                // Read string length
                if(!remaining(sizeof(sizetag_t))) {
                    return false;
                }
                sizetag_t length = read_length();

                // Read string
                if(!remaining(length)) {
                    return false;
                }
                string str((const char*)in + offset, length);
                offset += length;

                // Enquoute and escape string then output
                format_quoted('"', str, out);
            } else {
                // Otherwise format as an array of char
                out << '[';
                // Read array byte length
                if(!remaining(sizeof(sizetag_t))) {
                    out << ']';
                    return false;
                }
                sizetag_t length = read_length();

                if(length == 0) {
                    out << ']';
                    break;
                }

                // Read array
                if(!remaining(length)) {
                    out << ']';
                    return false;
                }
                size_t array_end = offset + length;

                const ArrayType* arr = dtype->as_array();
                bool ok = format(arr->get_element_type());
                if(!ok) {
                    out << ']';
                    return false;
                }

                while(offset < array_end) {
                    out << ", ";
                    ok = format(arr->get_element_type());
                    if(!ok) {
                        out << ']';
                        return false;
                    }
                }

                // Check to make sure we didn't overshoot the array while reading
                if(offset > array_end) {
                    out << ']';
                    return false;
                }

                out << ']';
            }

            break;
        }
        case T_BLOB: {
            // Read blob length
            sizetag_t length = dtype->get_size();

            // If we have a blob alias format as a hex constant
            if(dtype->has_alias() && dtype->get_alias() == "blob") {
                // Read blob
                if(!remaining(length)) {
                    return false;
                }
                string blob((const char*)in + offset, length);
                offset += length;

                // Format blob as a hex constant then output
                format_hex(blob, out);
            } else {
                // Otherwise format as an array of uint8
                out << '[';
                const ArrayType* arr = dtype->as_array();
                bool ok = format(arr->get_element_type());
                if(!ok) {
                    out << ']';
                    return false;
                }

                for(unsigned int i = 1; i < arr->get_array_size(); ++i) {
                    out << ", ";
                    ok = format(arr->get_element_type());
                    if(!ok) {
                        out << ']';
                        return false;
                    }
                }

                out << ']';
            }

            break;
        }
        case T_VARBLOB: {
            // If we have a blob alias format as a hex constant
            if(dtype->has_alias() && dtype->get_alias() == "blob") {
                // Read blob length
                if(!remaining(sizeof(sizetag_t))) {
                    return false;
                }
                sizetag_t length = read_length();


                // Read blob with length
                if(!remaining(length)) {
                    return false;
                }
                string blob((const char*)in + offset - 2, length + 2);
                offset += length;

                // Format blob and length as a hex constant then output
                format_hex(blob, out);
            } else {
                // Otherwise format as an array of uint8
                out << '[';
                // Read array byte length
                if(!remaining(sizeof(sizetag_t))) {
                    out << ']';
                    return false;
                }
                sizetag_t length = read_length();

                if(length == 0) {
                    out << ']';
                    break;
                }
                // Read array
                if(!remaining(length)) {
                    out << ']';
                    return false;
                }
                size_t array_end = offset + length;

                const ArrayType* arr = dtype->as_array();
                bool ok = format(arr->get_element_type());
                if(!ok) {
                    out << ']';
                    return false;
                }
                while(offset < array_end) {
                    out << ", ";
                    ok = format(arr->get_element_type());
                    if(!ok) {
                        out << ']';
                        return false;
                    }
                }

                // Check to make sure we didn't overshoot the array while reading
                if(offset > array_end) {
                    out << ']';
                    return false;
                }

                out << ']';
            }

            break;
        }
        case T_ARRAY: {
            out << '[';
            const ArrayType* arr = dtype->as_array();
            bool ok = format(arr->get_element_type());
            if(!ok) {
                out << ']';
                return false;
            }
            for(unsigned int i = 1; i < arr->get_array_size(); ++i) {
                out << ", ";
                ok = format(arr->get_element_type());
                if(!ok) {
                    out << ']';
                    return false;
                }
            }

            out << ']';
            break;
        }
        case T_VARARRAY: {
            out << '[';
            // Read array byte length
            if(!remaining(sizeof(sizetag_t))) {
                out << ']';
                return false;
            }
            sizetag_t length = read_length();

            if(length == 0) {
                out << ']';
                break;
            }

            // Read array
            if(!remaining(length)) {
                out << ']';
                return false;
            }
            size_t array_end = offset + length;

            const ArrayType* arr = dtype->as_array();
            bool ok = format(arr->get_element_type());
            if(!ok) {
                out << ']';
                return false;
            }
            while(offset < array_end) {
                out << ", ";
                ok = format(arr->get_element_type());
                if(!ok) {
                    out << ']';
                    return false;
                }
            }

            // Check to make sure we didn't overshoot the array while reading
            if(offset > array_end) {
                out << ']';
                return false;
            }

            out << ']';
            break;
        }
        case T_STRUCT: {
            out << '{';
            const Struct* strct = dtype->as_struct();
            size_t num_fields = strct->get_num_fields();
            if(num_fields > 0) {
                bool ok = format(strct->get_field(0)->get_type());
                if(!ok) {
                    out << '}';
                    return false;
                }
                for(unsigned int i = 1; i < num_fields; ++i) {
                    out << ", ";
                    ok = format(strct->get_field(i)->get_type());
                    if(!ok) {
                        out << '}';
                        return false;
                    }
                }
            }
            out << '}';
            break;
        }
        case T_METHOD: {
            out << '(';
            const Method* method = dtype->as_method();
            size_t num_params = method->get_num_parameters();
            if(num_params > 0) {
                bool ok = format(method->get_parameter(0)->get_type());
                if(!ok) {
                    out << ')';
                    return false;
                }
                for(unsigned int i = 1; i < num_params; ++i) {
                    out << ", ";
                    ok = format(method->get_parameter(i)->get_type());
                    if(!ok) {
                        out << ')';
                        return false;
                    }
                }
            }
            out << ')';
            break;
        }
        default: {
            out << "<error>";
            return false;
        }
        }
        return true;
    }
Exemplo n.º 29
0
string format_hex(const string &str)
{
    ostringstream ss;
    format_hex(str, ss);
    return ss.str();
}
Exemplo n.º 30
0
void
openvpn_encrypt (struct buffer *buf, struct buffer work,
		 const struct crypto_options *opt,
		 const struct frame* frame)
{
  struct gc_arena gc;
  gc_init (&gc);

  if (buf->len > 0 && opt->key_ctx_bi)
    {
      struct key_ctx *ctx = &opt->key_ctx_bi->encrypt;

      /* Do Encrypt from buf -> work */
      if (ctx->cipher)
	{
	  uint8_t iv_buf[OPENVPN_MAX_IV_LENGTH];
	  const int iv_size = cipher_ctx_iv_length (ctx->cipher);
	  const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt (ctx->cipher);
	  int outlen;

	  if (cipher_kt_mode_cbc(cipher_kt))
	    {
	      CLEAR (iv_buf);

	      /* generate pseudo-random IV */
	      if (opt->flags & CO_USE_IV)
		prng_bytes (iv_buf, iv_size);

	      /* Put packet ID in plaintext buffer or IV, depending on cipher mode */
	      if (opt->packet_id)
		{
		  struct packet_id_net pin;
		  packet_id_alloc_outgoing (&opt->packet_id->send, &pin, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM));
		  ASSERT (packet_id_write (&pin, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true));
		}
	    }
	  else if (cipher_kt_mode_ofb_cfb(cipher_kt))
	    {
	      struct packet_id_net pin;
	      struct buffer b;

	      ASSERT (opt->flags & CO_USE_IV);    /* IV and packet-ID required */
	      ASSERT (opt->packet_id); /*  for this mode. */

	      packet_id_alloc_outgoing (&opt->packet_id->send, &pin, true);
	      memset (iv_buf, 0, iv_size);
	      buf_set_write (&b, iv_buf, iv_size);
	      ASSERT (packet_id_write (&pin, &b, true, false));
	    }
	  else /* We only support CBC, CFB, or OFB modes right now */
	    {
	      ASSERT (0);
	    }

	  /* initialize work buffer with FRAME_HEADROOM bytes of prepend capacity */
	  ASSERT (buf_init (&work, FRAME_HEADROOM (frame)));

	  /* set the IV pseudo-randomly */
	  if (opt->flags & CO_USE_IV)
	    dmsg (D_PACKET_CONTENT, "ENCRYPT IV: %s", format_hex (iv_buf, iv_size, 0, &gc));

	  dmsg (D_PACKET_CONTENT, "ENCRYPT FROM: %s",
	       format_hex (BPTR (buf), BLEN (buf), 80, &gc));

	  /* cipher_ctx was already initialized with key & keylen */
	  ASSERT (cipher_ctx_reset(ctx->cipher, iv_buf));

	  /* Buffer overflow check */
	  if (!buf_safe (&work, buf->len + cipher_ctx_block_size(ctx->cipher)))
	    {
	      msg (D_CRYPT_ERRORS, "ENCRYPT: buffer size error, bc=%d bo=%d bl=%d wc=%d wo=%d wl=%d cbs=%d",
		   buf->capacity,
		   buf->offset,
		   buf->len,
		   work.capacity,
		   work.offset,
		   work.len,
		   cipher_ctx_block_size (ctx->cipher));
	      goto err;
	    }

	  /* Encrypt packet ID, payload */
	  ASSERT (cipher_ctx_update (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf)));
	  ASSERT (buf_inc_len(&work, outlen));

	  /* Flush the encryption buffer */
	  ASSERT (cipher_ctx_final(ctx->cipher, BPTR (&work) + outlen, &outlen));
	  ASSERT (buf_inc_len(&work, outlen));

	  /* For all CBC mode ciphers, check the last block is complete */
	  ASSERT (cipher_kt_mode (cipher_kt) != OPENVPN_MODE_CBC ||
	      outlen == iv_size);

	  /* prepend the IV to the ciphertext */
	  if (opt->flags & CO_USE_IV)
	    {
	      uint8_t *output = buf_prepend (&work, iv_size);
	      ASSERT (output);
	      memcpy (output, iv_buf, iv_size);
	    }

	  dmsg (D_PACKET_CONTENT, "ENCRYPT TO: %s",
	       format_hex (BPTR (&work), BLEN (&work), 80, &gc));
	}
      else				/* No Encryption */
	{
	  if (opt->packet_id)
	    {
	      struct packet_id_net pin;
	      packet_id_alloc_outgoing (&opt->packet_id->send, &pin, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM));
	      ASSERT (packet_id_write (&pin, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true));
	    }
	  work = *buf;
	}

      /* HMAC the ciphertext (or plaintext if !cipher) */
      if (ctx->hmac)
	{
	  uint8_t *output = NULL;

	  hmac_ctx_reset (ctx->hmac);
	  hmac_ctx_update (ctx->hmac, BPTR(&work), BLEN(&work));
	  output = buf_prepend (&work, hmac_ctx_size(ctx->hmac));
	  ASSERT (output);
	  hmac_ctx_final (ctx->hmac, output);
	}

      *buf = work;
    }

  gc_free (&gc);
  return;

err:
  crypto_clear_error();
  buf->len = 0;
  gc_free (&gc);
  return;
}