Beispiel #1
0
hash_stat hash_plugin_parse_hash(char *hashline, char *filename)
{
    char username[HASHFILE_MAX_LINE_LENGTH];
    char hash[HASHFILE_MAX_LINE_LENGTH];
    char line[HASHFILE_MAX_LINE_LENGTH];
    char line2[HASHFILE_MAX_LINE_LENGTH];
    char myhash[200];
    char mysalt[100];
    int blen;
    char *temp_str=NULL;
    
    bzero(myhash,200);
    bzero(mysalt,100);
    
    if (!hashline) return hash_err;
    if (!strstr(hashline,"{SSHA}")) return hash_err;
    if (strlen(hashline)<2) return hash_err;
    
    snprintf(line, HASHFILE_MAX_LINE_LENGTH-1, "%s", hashline);
    if (strstr(line,":"))
    {
	strcpy(username, strtok(line, ":"));
	temp_str=strtok(NULL,":");
    }
    else strcpy(username,"N/A");
    
    if (temp_str)
    {
	strcpy(hash, temp_str);
	strcpy(myhash,hash);
	if (memcmp(myhash, "{SSHA}", 6)!=0) return hash_err;
	(void)hash_add_username(username);
	(void)hash_add_hash(myhash, 0);
	blen = b64_pton(hash+6, (unsigned char *)line2, HASHFILE_MAX_LINE_LENGTH);
	line2[blen]=0;
	memcpy(mysalt,line2+20,8);
	mysalt[8]=0;
	mysalt[9]=0;
	(void)hash_add_salt(mysalt);
    }
    else
    {
	strcpy(myhash,line);
	if (memcmp(myhash, "{SSHA}", 6)!=0) return hash_err;
	(void)hash_add_username("N/A");
	(void)hash_add_hash(myhash, 0);
	blen = b64_pton(myhash+6, (unsigned char *)line2, HASHFILE_MAX_LINE_LENGTH);
	line2[blen]=0;
	memcpy(mysalt,line2+20,8);
	mysalt[8]=0;
	(void)hash_add_salt(mysalt);
    }
    
    (void)hash_add_salt2("");
    return hash_ok;
}
Beispiel #2
0
int decode_hybi(char *src, size_t srclength, u_char *target, size_t targsize)
{
   char *start;
   int i = 0, j, len, sz = 0;
   
   if ((int)srclength <= 0)
   {
      return 0;
   }

   src[srclength] = '\0';
   start = src;
   if (start[1] < 126)
   {
      start += 2 * sizeof(char);
      sz += 2;
   }
   else if (start[1] == 126)
   {
      start += 4 * sizeof(char);
      sz += 4;
   }
   else
   {
      start += 10 * sizeof(char);
      sz += 10;
   }

   if (src[1] & 0x80)
   {
      // we need to unmask the data
      //mask = ((char)start[0]) + ((char)start[1] << 8) + ((char)start[2] << 16) + ((char)start[3] << 24);
      i = 0;
      while (i < srclength - sz - 4)
      {
         j = i % 4;
         start[i + 4] ^= start[j];
         i += 1;            
      }

      start += 4 * sizeof(char);
      printf("%s\n", start);
      len = b64_pton((const char*)start, target, targsize);
   }
   else
   {
      len = b64_pton(src, target, targsize);
   }
   if (len < 0) {
      return len;
   }
   
   return len;
}
Beispiel #3
0
/** add tsig_key contents */
void
key_options_setup(region_type* region, key_options_t* key)
{
	uint8_t data[16384]; /* 16KB */
	int size;
	if(!key->tsig_key) {
		/* create it */
		key->tsig_key = (tsig_key_type *) region_alloc(region,
			sizeof(tsig_key_type));
		/* create name */
		key->tsig_key->name = dname_parse(region, key->name);
		if(!key->tsig_key->name) {
			log_msg(LOG_ERR, "Failed to parse tsig key name %s",
				key->name);
			/* key and base64 were checked during syntax parse */
			exit(1);
		}
		key->tsig_key->size = 0;
		key->tsig_key->data = NULL;
	}
	size = b64_pton(key->secret, data, sizeof(data));
	if(size == -1) {
		log_msg(LOG_ERR, "Failed to parse tsig key data %s",
			key->name);
		/* key and base64 were checked during syntax parse */
		exit(1);
	}
	key->tsig_key->size = size;
	key->tsig_key->data = (uint8_t *)region_alloc_init(region, data, size);
}
Beispiel #4
0
int decode_hixie(char *src, size_t srclength, u_char *target, size_t targsize) {
   char *start, *end, cntstr[4];
   int len, framecount = 0, retlen = 0;
   if ((src[0] != '\x00') || (src[srclength-1] != '\xff')) {
      handler_emsg("WebSocket framing error\n");
      return -1;
   }
   start = src+1; // Skip '\x00' start
   do {
      /* We may have more than one frame */
      end = (char *)memchr(start, '\xff', srclength);
      *end = '\x00';
      len = b64_pton(start, target+retlen, targsize-retlen);
      if (len < 0) {
         return len;
      }
      retlen += len;
      start = end + 2; // Skip '\xff' end and '\x00' start 
      framecount++;
   } while (end < (src+srclength-1));
   if (framecount > 1) {
      snprintf(cntstr, 3, "%d", framecount);
      traffic(cntstr);
   }
   return retlen;
}
Beispiel #5
0
int py_ersatz_hash(char *password, char *ersatz_salt, char *out_hash)
{
	/* todo: check the ersatz size */
	char hmac_digest[HMAC_LEN];
	int ret = py_hsm_hmac(password, hmac_digest);
	if(ret != HSM_HMAC_OK)
		return ERSATZ_HASH_FAIL;
	int i;
	char decoded_salt[SALT_SIZE ];
	/* convert back from . to + */
	for(i = 0; i < SALT_SIZE; i++)
		if(ersatz_salt[i] == '.')
			ersatz_salt[i] = '+';
	
	/* base64 decode ersatz salt   */
	b64_pton((unsigned char *) ersatz_salt, decoded_salt, SALT_SIZE);
	
	/* xor the hmac digest with the salt */
	for(i = 0; i < SALT_SIZE; i++)
		hmac_digest[i] = hmac_digest[i] ^ decoded_salt[i];
	
	for(i = 0; i < SALT_SIZE; i++)
		if(ersatz_salt[i] == '+')
			ersatz_salt[i] = '.';
	
	/* take a sha-512 hash */
	crypt_set_format("sha512");
	strcpy(out_hash, crypt(hmac_digest, ersatz_salt));
	return ERSATZ_HASH_OK;
}
Beispiel #6
0
static bool
asignify_pubkey_try_obsd(const char *buf, size_t buflen,
	struct asignify_public_data **pk)
{
	struct obsd_pubkey opk;
	struct asignify_public_data *res;

	if (buflen >= sizeof(OBSD_COMMENTHDR) - 1 &&
			memcmp(buf, OBSD_COMMENTHDR, sizeof(OBSD_COMMENTHDR) - 1) == 0) {
		/* Skip comments */
		return (true);
	}

	if (b64_pton(buf, (unsigned char *)&opk, sizeof(opk)) == sizeof(opk)) {
		if (memcmp(opk.pkalg, OBSD_PKALG, sizeof(opk.pkalg)) == 0) {
			res = xmalloc(sizeof(*res));
			/* OpenBSD version code */
			res->version = 0;
			res->data_len = sizeof(opk.pubkey);
			res->id_len = sizeof(opk.keynum);
			asignify_alloc_public_data_fields(res);
			memcpy(res->data, opk.pubkey, res->data_len);
			memcpy(res->id, opk.keynum, res->id_len);

			*pk = res;
		}
	}

	/*
	 * We stop processing on the first non-comment line. If we have a key,
	 * then we set *pk to some openbsd key, otherwise this variable is not
	 * touched
	 */
	return (false);
}
Beispiel #7
0
int
sshbuf_b64tod(struct sshbuf *buf, const char *b64)
{
	size_t plen = strlen(b64);
	int nlen, r;
	u_char *p;

	if (plen == 0)
		return 0;
	if ((p = malloc(plen)) == NULL)
		return SSH_ERR_ALLOC_FAIL;
	if ((nlen = b64_pton(b64, p, plen)) < 0) {
		bzero(p, plen);
		free(p);
		return SSH_ERR_INVALID_FORMAT;
	}
	if ((r = sshbuf_put(buf, p, nlen)) < 0) {
		bzero(p, plen);
		free(p);
		return r;
	}
	bzero(p, plen);
	free(p);
	return 0;
}
Beispiel #8
0
int
dst_s_conv_bignum_b64_to_u8(const char **buf,
			    u_char *loc, const unsigned loclen)
{
	unsigned blen;
	char *bp;
	u_char bstr[RAW_KEY_SIZE];
	int res = 0;

	if (buf == NULL || *buf == NULL) {	/* error checks */
		EREPORT(("dst_s_conv_bignum_b64_to_u8: null input buffer.\n"));
		return (0);
	}
	bp = strchr(*buf, '\n');	/* find length of input line */
	if (bp != NULL)
		*bp = '\0';

	res = b64_pton(*buf, bstr, sizeof(bstr));
	if (res <= 0) {
		EREPORT(("dst_s_conv_bignum_b64_to_u8: decoded value is null.\n"));
		return (0);
	}
	blen = (unsigned) res;
	if (loclen < blen) {
		EREPORT(("dst_s_conv_bignum_b64_to_u8: decoded value is longer than output buffer.\n"));
		return (0);
	}
	if (bp)
		*buf = bp;	/* advancing buffer past \n */
	memset(loc, 0, loclen - blen);	/* clearing unused output area */
	memcpy(loc + loclen - blen, bstr, blen);	/* write last blen bytes  */
	return (blen);
}
Beispiel #9
0
void key_options_tsig_add(nsd_options_t* opt)
{
	key_options_t* optkey;
	uint8_t data[4000];
	tsig_key_type* tsigkey;
	const dname_type* dname;
	int size;

	for(optkey = opt->keys; optkey; optkey = optkey->next)
	{
		dname = dname_parse(opt->region, optkey->name);
		if(!dname) {
			log_msg(LOG_ERR, "Failed to parse tsig key name %s", optkey->name);
			continue;
		}
		size = b64_pton(optkey->secret, data, sizeof(data));
		if(size == -1) {
			log_msg(LOG_ERR, "Failed to parse tsig key data %s", optkey->name);
			continue;
		}
		tsigkey = (tsig_key_type *) region_alloc(opt->region, sizeof(tsig_key_type));
		tsigkey->name = dname;
		tsigkey->size = size;
		tsigkey->data = (uint8_t *) region_alloc_init(opt->region, data, tsigkey->size);
		tsig_add_key(tsigkey);
		optkey->tsig_key = tsigkey;
	}
}
Beispiel #10
0
/*
 * read user's pubkeyring file to allow lookup by ident
 */
static const struct pubkey *
findpubkey(const char *ident)
{
	static struct {
		char ident[IDENTLEN];
		struct pubkey pubkey;
	} *keys;
	static int numkeys;
	static int done;
	int i;
	const char *beginreop = "-----BEGIN REOP PUBLIC KEY----\n";
	const char *endreop = "-----END REOP PUBLIC KEY-----\n";

	if (!done) {
		char line[1024];
		char buf[1024];
		int identline;
		FILE *fp;
		
		done = 1;
		fp = fopen(gethomefile("pubkeyring"), "r");
		if (!fp)
			return NULL;

		while (fgets(line, sizeof(line), fp)) {
			buf[0] = 0;
			identline = 1;
			if (line[0] == 0 || line[0] == '\n')
				continue;
			if (strncmp(line, beginreop, strlen(beginreop)) != 0)
				errx(1, "invalid keyring line: %s", line);
			if (!(keys = realloc(keys, sizeof(*keys) * (numkeys + 1))))
				err(1, "realloc keyring");
			while (1) {
				if (!fgets(line, sizeof(line), fp))
					errx(1, "premature pubkeyring EOF");
				if (identline) {
					readident(line, keys[numkeys].ident);
					identline = 0;
					continue;
				}
				if (strncmp(line, endreop, strlen(endreop)) == 0)
					break;
				strlcat(buf, line, sizeof(buf));
			}
			if (b64_pton(buf, (void *)&keys[numkeys].pubkey,
			    sizeof(keys[0].pubkey)) != sizeof(keys[0].pubkey))
				errx(1, "invalid keyring b64 encoding");
			if (numkeys++ > 1000000)
				errx(1, "too many keys");
		}
	}
	for (i = 0; i < numkeys; i++) {
		if (strcmp(ident, keys[i].ident) == 0)
			return &keys[i].pubkey;
	}
	return NULL;
}
Beispiel #11
0
static void unbase64(uint8_t dstkey[32], const char *srckey)
{
	uint8_t buf[33];
	if (b64_pton(srckey, buf, 33) != 32) {
		fprintf(stderr, "Could not parse base64 key: %s\n", srckey);
		exit(EINVAL);
	}
	memcpy(dstkey, buf, 32);
}
Beispiel #12
0
TEST(resolv, b64_pton_28035006) {
  // Test data from https://groups.google.com/forum/#!topic/mailing.openbsd.tech/w3ACIlklJkI.
  const char* data =
      "p1v3+nehH3N3n+/OokzXpsyGF2VVpxIxkjSn3Mv/Sq74OE1iFuVU+K4bQImuVj"
      "S55RB2fpCpbB8Nye7tzrt6h9YPP3yyJfqORDETGmIB4lveZXA4KDxx50F9rYrO"
      "dFbTLyWfNBb/8Q2TnD72eY/3Y5P9qwtJwyDL25Tleic8G3g=";

  // This buffer is exactly the right size, but old versions of the BSD code
  // incorrectly required an extra byte. http://b/28035006.
  uint8_t buf[128];
  ASSERT_EQ(128, b64_pton(data, buf, sizeof(buf)));
}
Beispiel #13
0
/* Base64 decode string. */
char *
imap_base64_decode(char *in)
{
	char	*out;
	size_t	 size;

	size = (strlen(in) * 4) + 1;
	out = xcalloc(1, size);
	if (b64_pton(in, out, size) < 0) {
		xfree(out);
		return (NULL);
	}
	return (out);
}
Beispiel #14
0
static int
urlsafe_base64_decode(const char *base64, u_char *buffer, size_t bufferlen)
{
	// U2F uses urlsafe base64, which replaces + with - and / with _, so we
	// need to revert that before base64 decoding.
	char *replaced;
	char *pos;

	replaced = xstrdup(base64);
	while ((pos = strchr(replaced, '-')) != NULL)
        *pos = '+';
	while ((pos = strchr(replaced, '_')) != NULL)
		*pos = '/';

	return b64_pton(replaced, buffer, bufferlen);
}
Beispiel #15
0
/*
 * message followed by signature in one file
 */
static void
verifyembedded(const char *pubkeyfile, const char *sigfile, int quiet)
{
	char ident[IDENTLEN];
	struct sig sig;
	struct pubkey pubkey;
	uint8_t *msg;
	unsigned long long msglen;
	uint8_t *msgdata;
	unsigned long long msgdatalen;
	char *begin, *end;
	const char *beginreopmsg = "-----BEGIN REOP SIGNED MESSAGE-----\n";
	const char *beginreopsig = "-----BEGIN REOP SIGNATURE-----\n";
	const char *endreopmsg = "-----END REOP SIGNED MESSAGE-----\n";

	msgdata = readall(sigfile, &msgdatalen);
	if (strncmp(msgdata, beginreopmsg, strlen(beginreopmsg)) != 0)
 		goto fail;
	begin = msgdata + 36;
	if (!(end = strstr(begin, beginreopsig)))
 		goto fail;
	*end = 0;

	msg = begin;
	msglen = end - begin;

	begin = end + 31;
	if (!(end = strstr(begin, endreopmsg)))
 		goto fail;
	*end = 0;

	begin = readident(begin, ident);
	if (b64_pton(begin, (void *)&sig, sizeof(sig)) != sizeof(sig))
 		goto fail;

	getpubkey(pubkeyfile, ident, &pubkey);

	verifymsg(&pubkey, msg, msglen, &sig, quiet);

	free(msgdata);

	return;
fail:
	errx(1, "invalid signature: %s", sigfile);
}
Beispiel #16
0
uint16_t *
zparser_conv_b64(region_type *region, const char *b64)
{
	uint8_t buffer[B64BUFSIZE];
	uint16_t *r = NULL;
	int i;

	if(strcmp(b64, "0") == 0) {
		/* single 0 represents empty buffer */
		return alloc_rdata(region, 0);
	}
	i = b64_pton(b64, buffer, B64BUFSIZE);
	if (i == -1) {
		zc_error_prev_line("invalid base64 data");
	} else {
		r = alloc_rdata_init(region, buffer, i);
	}
	return r;
}
Beispiel #17
0
/* 
 * Verify an SHA cancel key against a cancel lock.
 * Returns 0 on success, nonzero on failure.
 */
int md5_verify(unsigned char *key, unsigned char *lock)
{
    unsigned char binkey[MD5_LENGTH + 4];
    unsigned char templock[BUFFSIZE];
    unsigned char hmacbuff[MD5_LENGTH];
    MD5_CTX hash_ctx;
    int verified;

    /* Convert the key back into binary */
    (void) b64_pton(key, binkey, (MD5_LENGTH + 4));

    MD5Init(&hash_ctx);
    MD5Update(&hash_ctx, key, strlen(key));
    MD5Final(hmacbuff, &hash_ctx);
    (void) b64_ntop(hmacbuff, MD5_LENGTH, templock, BUFFSIZE);

    verified = strcmp(templock, lock);

    return (verified);
}
Beispiel #18
0
int decode_hixie(char *src, size_t srclength,
                 u_char *target, size_t targsize,
                 unsigned int *opcode, unsigned int *left) {
    char *start, *end, cntstr[4];
    int i, len, framecount = 0, retlen = 0;
    unsigned char chr;
    if ((src[0] != '\x00') || (src[srclength-1] != '\xff')) {
        handler_emsg("WebSocket framing error\n");
        return -1;
    }
    *left = srclength;

    if (srclength == 2 &&
        (src[0] == '\xff') && 
        (src[1] == '\x00')) {
        // client sent orderly close frame
        *opcode = 0x8; // Close frame
        return 0;
    }
    *opcode = 0x1; // Text frame

    start = src+1; // Skip '\x00' start
    do {
        /* We may have more than one frame */
        end = (char *)memchr(start, '\xff', srclength);
        *end = '\x00';
        len = b64_pton(start, target+retlen, targsize-retlen);
        if (len < 0) {
            return len;
        }
        retlen += len;
        start = end + 2; // Skip '\xff' end and '\x00' start 
        framecount++;
    } while (end < (src+srclength-1));
    if (framecount > 1) {
        snprintf(cntstr, 3, "%d", framecount);
        traffic(cntstr);
    }
    *left = 0;
    return retlen;
}
Beispiel #19
0
static int
dst_hmac_md5_key_from_file_format(DST_KEY *dkey, const char *buff,
			      const int buff_len)
{
	const char *p = buff, *eol;
	u_char key[HMAC_LEN+1];	/* b64_pton needs more than 64 bytes do decode
				 * it should probably be fixed rather than doing
				 * this
				 */
	u_char *tmp;
	int key_len, len;

	if (dkey == NULL)
		return (-2);
	if (buff == NULL || buff_len < 0)
		return (-1);

	memset(key, 0, sizeof(key));

	if (!dst_s_verify_str(&p, "Key: "))
		return (-3);

	eol = strchr(p, '\n');
	if (eol == NULL)
		return (-4);
	len = eol - p;
	tmp = malloc(len + 2);
	if (tmp == NULL)
		return (-5);
	memcpy(tmp, p, len);
	*(tmp + len) = 0x0;
	key_len = b64_pton((char *)tmp, key, HMAC_LEN+1);	/*%< see above */
	SAFE_FREE2(tmp, len + 2);

	if (dst_buffer_to_hmac_md5(dkey, key, key_len) < 0) {
		return (-6);
	}
	return (0);
}
Beispiel #20
0
static int
chap_b642bin(const char *b64, void **binp, size_t *bin_lenp)
{
    char *bin;
    int b64_len, bin_len;

    b64_len = strlen(b64);
    bin_len = (b64_len + 3) / 4 * 3;
    bin = calloc(bin_len, 1);
    if (bin == NULL)
        log_err(1, "calloc");

    bin_len = b64_pton(b64, bin, bin_len);
    if (bin_len < 0) {
        log_warnx("malformed base64 variable");
        free(bin);
        return (-1);
    }
    *binp = bin;
    *bin_lenp = bin_len;
    return (0);
}
Beispiel #21
0
static void
putb64(FILE *out, const char *inb, size_t *inblen)
{
	char inbuf[5] = { 0 };
	unsigned char outbuf[3];
	ssize_t outbuflen;

	if (*inblen == 0)
		return;

	assert(*inblen <= 4);
	memcpy(inbuf, inb, *inblen);
	outbuflen = b64_pton(inbuf, outbuf, sizeof outbuf);
	if (outbuflen <= 0) {
		DPRINTF("invalid Base64 data");
		die(1);
	}
	if (fwrite(outbuf, outbuflen, 1, out) != 1) {
		perror("fwrite");
		die(1);
	}
	*inblen = 0;
}
Beispiel #22
0
/*
 * try to read a few different kinds of files 
 */
static void
readkeyfile(const char *filename, void *key, size_t keylen, char *ident)
{
	char *keydata;
	unsigned long long keydatalen;
	char *begin, *end;
	const char *beginreop = "-----BEGIN REOP";
	const char *endreop = "-----END REOP";

	keydata = readall(filename, &keydatalen);
	if (strncmp(keydata, beginreop, strlen(beginreop)) != 0 ||
	    !(end = strstr(keydata, endreop)))
		errx(1, "invalid key: %s", filename);
	*end = 0;
	if (!(begin = strchr(keydata, '\n')))
		errx(1, "invalid key: %s", filename);
	begin = readident(begin + 1, ident);
	*end = 0;
	if (b64_pton(begin, key, keylen) != keylen)
		errx(1, "invalid b64 encoding: %s", filename);

	xfree(keydata, keydatalen);
}
Beispiel #23
0
void switch_value(lua_State *L, int index, bson_t* bson, int level, const char* key)
{
    switch(lua_type(L, index))
    {
      case LUA_TTABLE:
      {
        int is_a=is_array(L, index);

        if (is_a)
        {
          bson_t child;
          //start array
          BSON_APPEND_ARRAY_BEGIN(bson, key, &child);
          iterate_table(L, index, &child, 0, level+1, NULL);
          bson_append_array_end(bson, &child);
        }
        else
        {
          bson_t child;
          //start map
          BSON_APPEND_DOCUMENT_BEGIN(bson, key, &child);
          iterate_table(L, index, &child, 1, level+1, NULL);
          bson_append_document_end(bson, &child);
        }
        break;
      }

      case LUA_TNIL:
      {
        BSON_APPEND_NULL(bson, key);
        break;
      }

      case LUA_TNUMBER:
      {
        BSON_APPEND_DOUBLE(bson, key, lua_tonumber(L, index));
        break;
      }

      case LUA_TBOOLEAN:
      {
        BSON_APPEND_BOOL(bson, key, lua_toboolean(L, index));
        break;
      }

      case LUA_TSTRING:
      {
        BSON_APPEND_UTF8(bson, key, lua_tostring(L, index));
        break;
      }

      case LUA_TUSERDATA:
      {
        // switch userdata type
        if (luaL_checkudata_ex(L, index, REGEX_METATABLE))
        {
          cbson_regex_t* regex = check_cbson_regex(L, index);

          BSON_APPEND_REGEX (bson, key, regex->regex, regex->options);
        }
        else if (luaL_checkudata_ex(L, index, OID_METATABLE))
        {
          cbson_oid_t* oid = check_cbson_oid(L, index);
          bson_oid_t boid;

          bson_oid_init_from_string (&boid, oid->oid);

          BSON_APPEND_OID (bson, key, &boid);
        }
        else if (luaL_checkudata_ex(L, index, BINARY_METATABLE))
        {
          cbson_binary_t* bin = check_cbson_binary(L, index);

          size_t binary_len = b64_pton (bin->data, NULL, 0);
          unsigned char* buf=malloc(binary_len+1);
          b64_pton(bin->data, buf, binary_len+1);

          BSON_APPEND_BINARY(bson, key, bin->type, buf, binary_len);

          free(buf);
        }
        else if (luaL_checkudata_ex(L, index, SYMBOL_METATABLE))
        {
          cbson_symbol_t* sym = check_cbson_symbol(L, index);

          BSON_APPEND_SYMBOL(bson, key, sym->symbol);
        }
        else if (luaL_checkudata_ex(L, index, REF_METATABLE))
        {
          cbson_ref_t* ref = check_cbson_ref(L, index);

          bson_oid_t boid;
          bson_oid_init_from_string (&boid, ref->id);

          BSON_APPEND_DBPOINTER(bson, key, ref->ref, &boid);
        }
        else if (luaL_checkudata_ex(L, index, MINKEY_METATABLE))
        {
          check_cbson_minkey(L, index);
          BSON_APPEND_MINKEY(bson, key);
        }
        else if (luaL_checkudata_ex(L, index, MAXKEY_METATABLE))
        {
          check_cbson_maxkey(L, index);
          BSON_APPEND_MAXKEY(bson, key);
        }
        else if (luaL_checkudata_ex(L, index, TIMESTAMP_METATABLE))
        {
          cbson_timestamp_t* time = check_cbson_timestamp(L, index);
          BSON_APPEND_TIMESTAMP(bson, key, time->timestamp, time->increment);
        }
        else if (luaL_checkudata_ex(L, index, INT64_METATABLE) || luaL_checkudata_ex(L, index, UINT64_METATABLE))
        {
          cbson_int64_t i = cbson_int64_check(L, index);
          if (i < INT32_MIN || i > INT32_MAX)
          {
            BSON_APPEND_INT64(bson, key, i);
          }
          else
          {
            BSON_APPEND_INT32(bson, key, (int32_t)i);
          }
        }
        else if (luaL_checkudata_ex(L, index, CODE_METATABLE))
        {
          cbson_code_t* code = check_cbson_code(L, index);
          BSON_APPEND_CODE(bson, key, code->code);
        }
        else if (luaL_checkudata_ex(L, index, CODEWSCOPE_METATABLE))
        {
          cbson_codewscope_t* code = check_cbson_codewscope(L, index);
          BSON_APPEND_CODE_WITH_SCOPE(bson, key, code->code, NULL);
        }
        else if (luaL_checkudata_ex(L, index, UNDEFINED_METATABLE))
        {
          check_cbson_undefined(L, index);
          BSON_APPEND_UNDEFINED(bson, key);
        }
        else if (luaL_checkudata_ex(L, index, DATE_METATABLE))
        {
          BSON_APPEND_DATE_TIME(bson, key, cbson_date_check(L, index));
        }
        break;
      }
      case LUA_TFUNCTION:
      case LUA_TTHREAD:
      case LUA_TLIGHTUSERDATA:
      default:
        break; // or bail out?
    }

}
Beispiel #24
0
static int
_bson_json_read_string (void                *_ctx, /* IN */
                        const unsigned char *val,  /* IN */
                        size_t               vlen) /* IN */
{
   bson_json_read_state_t rs;
   bson_json_read_bson_state_t bs;

   BASIC_YAJL_CB_PREAMBLE;

   rs = bson->read_state;
   bs = bson->bson_state;

   if (rs == BSON_JSON_REGULAR) {
      bson_append_utf8 (STACK_BSON_CHILD, key, (int)len, (const char *)val, (int)vlen);
   } else if (rs == BSON_JSON_IN_BSON_TYPE || rs ==
              BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES) {
      const char *val_w_null;
      _bson_json_buf_set (&bson->bson_type_buf[2], val, vlen, true);
      val_w_null = (const char *)bson->bson_type_buf[2].buf;

      switch (bs) {
      case BSON_JSON_LF_REGEX:
         bson->bson_type_data.regex.has_regex = true;
         _bson_json_buf_set (&bson->bson_type_buf[0], val, vlen, true);
         break;
      case BSON_JSON_LF_OPTIONS:
         bson->bson_type_data.regex.has_options = true;
         _bson_json_buf_set (&bson->bson_type_buf[1], val, vlen, true);
         break;
      case BSON_JSON_LF_OID:

         if (vlen != 24) {
            goto BAD_PARSE;
         }

         bson->bson_type_data.oid.has_oid = true;
         bson_oid_init_from_string (&bson->bson_type_data.oid.oid, val_w_null);
         break;
      case BSON_JSON_LF_TYPE:
         bson->bson_type_data.binary.has_subtype = true;

#ifdef _WIN32
# define SSCANF sscanf_s
#else
# define SSCANF sscanf
#endif

         if (SSCANF (val_w_null, "%02x",
                     &bson->bson_type_data.binary.type) != 1) {
            goto BAD_PARSE;
         }

#undef SSCANF

         break;
      case BSON_JSON_LF_BINARY: {
            /* TODO: error handling for pton */
            int binary_len;
            bson->bson_type_data.binary.has_binary = true;
            binary_len = b64_pton (val_w_null, NULL, 0);
            _bson_json_buf_ensure (&bson->bson_type_buf[0], binary_len + 1);
            b64_pton ((char *)bson->bson_type_buf[2].buf,
                      bson->bson_type_buf[0].buf, binary_len + 1);
            bson->bson_type_buf[0].len = binary_len;
            break;
         }
      case BSON_JSON_LF_REF:
         bson->bson_type_data.ref.has_ref = true;
         _bson_json_buf_set (&bson->bson_type_buf[0], val, vlen, true);
         break;
      case BSON_JSON_LF_ID:

         if (vlen != 24) {
            goto BAD_PARSE;
         }

         bson->bson_type_data.ref.has_id = true;
         bson_oid_init_from_string (&bson->bson_type_data.ref.id, val_w_null);
         break;
      case BSON_JSON_LF_INT64:
         {
            int64_t v64;
            char *endptr = NULL;

            errno = 0;
            v64 = bson_ascii_strtoll ((const char *)val, &endptr, 10);

            if (((v64 == INT64_MIN) || (v64 == INT64_MAX)) && (errno == ERANGE)) {
               goto BAD_PARSE;
            }

            if (endptr != ((const char *)val + vlen)) {
               goto BAD_PARSE;
            }

            bson_append_int64 (STACK_BSON_CHILD, key, (int)len, v64);
         }
         break;
      case BSON_JSON_LF_DATE:
      case BSON_JSON_LF_TIMESTAMP_T:
      case BSON_JSON_LF_TIMESTAMP_I:
      case BSON_JSON_LF_UNDEFINED:
      case BSON_JSON_LF_MINKEY:
      case BSON_JSON_LF_MAXKEY:
      default:
         goto BAD_PARSE;
      }

      return 1;

   BAD_PARSE:
      _bson_json_read_set_error (reader,
                                 "Invalid input string %s, looking for %d",
                                 val_w_null, bs);
      return 0;
   } else {
      _bson_json_read_set_error (reader, "Invalid state to look for string %d",
                                 rs);
      return 0;
   }

   return 1;
}
Beispiel #25
0
int decode_hybi(unsigned char *src, size_t srclength,
                u_char *target, size_t targsize,
                unsigned int *opcode, unsigned int *left)
{
    unsigned char *frame, *mask, *payload, save_char, cntstr[4];;
    int masked = 0;
    int i = 0, len, framecount = 0;
    size_t remaining;
    unsigned int target_offset = 0, hdr_length = 0, payload_length = 0;
    
    *left = srclength;
    frame = src;

    //printf("Deocde new frame\n");
    while (1) {
        // Need at least two bytes of the header
        // Find beginning of next frame. First time hdr_length, masked and
        // payload_length are zero
        frame += hdr_length + 4*masked + payload_length;
        //printf("frame[0..3]: 0x%x 0x%x 0x%x 0x%x (tot: %d)\n",
        //       (unsigned char) frame[0],
        //       (unsigned char) frame[1],
        //       (unsigned char) frame[2],
        //       (unsigned char) frame[3], srclength);

        if (frame > src + srclength) {
            //printf("Truncated frame from client, need %d more bytes\n", frame - (src + srclength) );
            break;
        }
        remaining = (src + srclength) - frame;
        if (remaining < 2) {
            //printf("Truncated frame header from client\n");
            break;
        }
        framecount ++;

        *opcode = frame[0] & 0x0f;
        masked = (frame[1] & 0x80) >> 7;

        if (*opcode == 0x8) {
            // client sent orderly close frame
            break;
        }

        payload_length = frame[1] & 0x7f;
        if (payload_length < 126) {
            hdr_length = 2;
            //frame += 2 * sizeof(char);
        } else if (payload_length == 126) {
            payload_length = (frame[2] << 8) + frame[3];
            hdr_length = 4;
        } else {
            handler_emsg("Receiving frames larger than 65535 bytes not supported\n");
            return -1;
        }
        if ((hdr_length + 4*masked + payload_length) > remaining) {
            continue;
        }
        //printf("    payload_length: %u, raw remaining: %u\n", payload_length, remaining);
        payload = frame + hdr_length + 4*masked;

        if (*opcode != 1 && *opcode != 2) {
            handler_msg("Ignoring non-data frame, opcode 0x%x\n", *opcode);
            continue;
        }

        if (payload_length == 0) {
            handler_msg("Ignoring empty frame\n");
            continue;
        }

        if ((payload_length > 0) && (!masked)) {
            handler_emsg("Received unmasked payload from client\n");
            return -1;
        }

        // Terminate with a null for base64 decode
        save_char = payload[payload_length];
        payload[payload_length] = '\0';

        // unmask the data
        mask = payload - 4;
        for (i = 0; i < payload_length; i++) {
            payload[i] ^= mask[i%4];
        }

        // base64 decode the data
        len = b64_pton((const char*)payload, target+target_offset, targsize);

        // Restore the first character of the next frame
        payload[payload_length] = save_char;
        if (len < 0) {
            handler_emsg("Base64 decode error code %d", len);
            return len;
        }
        target_offset += len;

        //printf("    len %d, raw %s\n", len, frame);
    }

    if (framecount > 1) {
        snprintf(cntstr, 3, "%d", framecount);
        traffic(cntstr);
    }
    
    *left = remaining;
    return target_offset;
}
Beispiel #26
0
static DST_KEY *
dst_s_read_public_key(const char *in_name, const u_int16_t in_id, int in_alg)
{
	int flags, proto, alg, len, dlen;
	int c;
	char name[PATH_MAX], enckey[RAW_KEY_SIZE], *notspace;
	u_char deckey[RAW_KEY_SIZE];
	FILE *fp;

	if (in_name == NULL) {
		EREPORT(("dst_read_public_key(): No key name given\n"));
		return (NULL);
	}
	if (dst_s_build_filename(name, in_name, in_id, in_alg, PUBLIC_KEY,
				 PATH_MAX) == -1) {
		EREPORT(("dst_read_public_key(): Cannot make filename from %s, %d, and %s\n",
			 in_name, in_id, PUBLIC_KEY));
		return (NULL);
	}
	/*
	 * Open the file and read it's formatted contents up to key
	 * File format:
	 *    domain.name [ttl] [IN] KEY  &lt;flags&gt; &lt;protocol&gt; &lt;algorithm&gt; &lt;key&gt;
	 * flags, proto, alg stored as decimal (or hex numbers FIXME).
	 * (FIXME: handle parentheses for line continuation.)
	 */
	if ((fp = dst_s_fopen(name, "r", 0)) == NULL) {
		EREPORT(("dst_read_public_key(): Public Key not found %s\n",
			 name));
		return (NULL);
	}
	/* Skip domain name, which ends at first blank */
	while ((c = getc(fp)) != EOF)
		if (isspace(c))
			break;
	/* Skip blank to get to next field */
	while ((c = getc(fp)) != EOF)
		if (!isspace(c))
			break;

	/* Skip optional TTL -- if initial digit, skip whole word. */
	if (isdigit(c)) {
		while ((c = getc(fp)) != EOF)
			if (isspace(c))
				break;
		while ((c = getc(fp)) != EOF)
			if (!isspace(c))
				break;
	}
	/* Skip optional "IN" */
	if (c == 'I' || c == 'i') {
		while ((c = getc(fp)) != EOF)
			if (isspace(c))
				break;
		while ((c = getc(fp)) != EOF)
			if (!isspace(c))
				break;
	}
	/* Locate and skip "KEY" */
	if (c != 'K' && c != 'k') {
		EREPORT(("\"KEY\" doesn't appear in file: %s", name));
		return NULL;
	}
	while ((c = getc(fp)) != EOF)
		if (isspace(c))
			break;
	while ((c = getc(fp)) != EOF)
		if (!isspace(c))
			break;
	ungetc(c, fp);		/*%< return the charcter to the input field */
	/* Handle hex!! FIXME.  */

	if (fscanf(fp, "%d %d %d", &flags, &proto, &alg) != 3) {
		EREPORT(("dst_read_public_key(): Can not read flag/proto/alg field from %s\n"
			 ,name));
		return (NULL);
	}
	/* read in the key string */
	fgets(enckey, sizeof(enckey), fp);

	/* If we aren't at end-of-file, something is wrong.  */
	while ((c = getc(fp)) != EOF)
		if (!isspace(c))
			break;
	if (!feof(fp)) {
		EREPORT(("Key too long in file: %s", name));
		return NULL;
	}
	fclose(fp);

	if ((len = strlen(enckey)) <= 0)
		return (NULL);

	/* discard \n */
	enckey[--len] = '\0';

	/* remove leading spaces */
	for (notspace = (char *) enckey; isspace((*notspace)&0xff); len--)
		notspace++;

	dlen = b64_pton(notspace, deckey, sizeof(deckey));
	if (dlen < 0) {
		EREPORT(("dst_read_public_key: bad return from b64_pton = %d",
			 dlen));
		return (NULL);
	}
	/* store key and info in a key structure that is returned */
/*	return dst_store_public_key(in_name, alg, proto, 666, flags, deckey,
				    dlen);*/
	return dst_buffer_to_key(in_name, alg, flags, proto, deckey, dlen);
}
Beispiel #27
0
/* Print to stdout detailed session summary */
hash_stat print_session_detailed(char *sessionname)
{
#ifdef HAVE_JSON_JSON_H
    FILE *sesfile;
    struct passwd *pwd;
    char sesname[1024];
    int cnt=0;
    char username[HASHFILE_MAX_LINE_LENGTH];
    char hash[HASHFILE_MAX_LINE_LENGTH];
    char rawhash[HASHFILE_MAX_LINE_LENGTH];
    char rawhash2[HASHFILE_MAX_LINE_LENGTH*2];
    char plugin_used[HASHFILE_MAX_LINE_LENGTH*2];
    char salt[HASHFILE_MAX_LINE_LENGTH];
    int flag = 0;
    json_object *jobj;
    
    printf("\nDetailed information about session: %s\n"
	    "-----------------------------------------------\n",sessionname);
    pwd = getpwuid(getuid());
    snprintf(sesname, 1024, "%s/.hashkill/sessions/%s.session", pwd->pw_dir, sessionname);
    /* Parse the <session>..</session> info */
    sesfile = fopen(sesname, "r");
    if (!sesfile)
    {
        elog("Cannot open session file : %s\n",sesname);
        return hash_err;
    }
    printf("Session file: \t%s\n",sesname);

    fclose(sesfile);
    root_node = json_object_from_file(sesname);
    main_header_node = json_object_object_get(root_node,"main");
    switch (json_object_get_int(json_object_object_get(main_header_node,"attacktype")))
    {
	case attack_method_simple_bruteforce:
	    printf("Attack type: \tBruteforce\n");
	    break;
	case attack_method_markov:
	    printf("Attack type: \tMarkov\n");
	    break;
	case attack_method_rule:
	    printf("Attack type: \tRule-based\n");
	    break;
	default:
	    printf("Attack type: \tUNKNOWN!\n");
	    break;
    }
    attack_method=json_object_get_int(json_object_object_get(main_header_node,"attacktype"));
    printf("Plugin: \t%s\n",json_object_get_string(json_object_object_get(main_header_node,"plugin")));
    printf("Progress: \t%d%%\n",json_object_get_int(json_object_object_get(main_header_node,"progress")));
    printf("Session ends: \t%s",json_object_get_string(json_object_object_get(main_header_node,"timestamp")));
    printf("Hashlist file: \t%s\n",json_object_get_string(json_object_object_get(main_header_node,"hashlistfile")));
    printf("Command line: \t%s\n",json_object_get_string(json_object_object_get(main_header_node,"commandline")));

    switch (attack_method)
    {
	case attack_method_simple_bruteforce:
	    attack_header_node = json_object_object_get(root_node,"bruteforce");
	    printf("\nBruteforce attack parameters:\n"
	             "-----------------------------\n");
	    printf("Start length: \t%d\n",json_object_get_int(json_object_object_get(attack_header_node,"start")));
	    printf("End length: \t%d\n",json_object_get_int(json_object_object_get(attack_header_node,"end")));
	    printf("Charset: \t%s\n",json_object_get_string(json_object_object_get(attack_header_node,"charset")));
	    printf("Current str: \t%s\n",json_object_get_string(json_object_object_get(attack_header_node,"currentstr")));
	break;
	case attack_method_markov:
	    attack_header_node = json_object_object_get(root_node,"markov");
	    printf("\nMarkov attack parameters:\n"
	             "-------------------------\n");
	    printf("Statfile: \t%s\n",json_object_get_string(json_object_object_get(attack_header_node,"statfile")));
	    printf("Threshold: \t%d\n",json_object_get_int(json_object_object_get(attack_header_node,"threshold")));
	    printf("End length: \t%d\n",json_object_get_int(json_object_object_get(attack_header_node,"maxlen")));
	    printf("Current str: \t%s\n",json_object_get_string(json_object_object_get(attack_header_node,"currentstr")));
	break;
	case attack_method_rule:
	    attack_header_node = json_object_object_get(root_node,"rule");
	    printf("\nRule attack parameters:\n"
	             "-----------------------\n");
	    printf("Rule file: \t%s\n",json_object_get_string(json_object_object_get(attack_header_node,"rulefile")));
	break;

    }
    printf("\nHashes list (username:hash:salt):\n---------------------------------\n");
    hash_list_node = json_object_object_get(root_node,"hashlist");
    flag = json_object_array_length(hash_list_node);
    for (cnt=0;cnt<flag;cnt++)
    {
	jobj = json_object_array_get_idx(hash_list_node, cnt);
	strcpy(username, json_object_get_string(json_object_object_get(jobj,"username")));
	strcpy(hash, json_object_get_string(json_object_object_get(jobj,"hash")));
	strcpy(salt, json_object_get_string(json_object_object_get(jobj,"salt")));
	// This is idiotic I know
	if ((strncmp(plugin_used,"md5unix",8)==0) || (strncmp(plugin_used,"sha512unix",10)==0) ||(strncmp(plugin_used,"phpbb3",6)==0) || (strncmp(plugin_used,"wordpress",9)==0) || (strncmp(plugin_used,"apr1",4)==0))
	{
	    b64_pton(hash,(unsigned char *)rawhash,512);
	    printf("%s:%s%s\n", username, salt, rawhash);
	}
	else if (  (strncmp(plugin_used,"desunix",7)==0)
		 || (strncmp(plugin_used,"ldap-sha",8)==0) || (strncmp(plugin_used,"ldap-ssha",9)==0))
	{
	    b64_pton(hash,(unsigned char *)rawhash,512);
	    printf("%s:%s:%s\n", username, rawhash, salt);
	}
	else
	{
	    str2hex(rawhash,rawhash2, (strlen(hash)*100)/147);
	    printf("%s:%s:%s\n", username, rawhash2, salt);
	}
    }
    cracked_list_node = json_object_object_get(root_node,"crackedlist");
    if (cracked_list_node)
    {
	cnt = json_object_array_length(cracked_list_node);
    }
    else
    {
	cnt=0;
    }
    printf("\n%d passwords cracked.\n",cnt);
    printf("\n");
    hlog("Session %s dumped successfully\n\n", sessionname);
    return hash_ok;
#else
    wlog("This build does not support sessions. Please reconfigure with --with-json and rebuild%s\n","");
    return hash_err;
#endif
}
Beispiel #28
0
TEST(resolv, b64_pton) {
  u_char buf[128];
  memset(buf, 'x', sizeof(buf));
  ASSERT_EQ(static_cast<int>(strlen("hello")), b64_pton("aGVsbG8=", buf, sizeof(buf)));
  ASSERT_STREQ(reinterpret_cast<char*>(buf), "hello");
}
Beispiel #29
0
int
main(int argc, char **argv) {
	short port = htons(NAMESERVER_PORT);
	short lport;
	/* Wierd stuff for SPARC alignment, hurts nothing else. */
	union {
		HEADER header_;
		u_char packet_[PACKETSZ];
	} packet_;
#define header (packet_.header_)
#define	packet (packet_.packet_)
	union {
		HEADER u;
		u_char b[NS_MAXMSG];
	} answer;
	int n;
	char doping[90];
	char pingstr[50];
	char *afile;
	char *addrc, *addrend, *addrbegin;

	time_t exectime;
	struct timeval tv1, tv2, start_time, end_time, query_time;

	char *srv;
	int anyflag = 0;
	int sticky = 0;
	int tmp; 
	int qtypeSet;
	ns_type xfr = ns_t_invalid;
        int bytes_out, bytes_in;

	char cmd[512];
	char domain[MAXDNAME];
        char msg[120], **vtmp;
	char *args[DIG_MAXARGS];
	char **ax;
	int once = 1, dofile = 0; /* batch -vs- interactive control */
	char fileq[384];
	int  fp;
	int wait=0, delay;
	int envset=0, envsave=0;
	struct __res_state res_x, res_t;
	int r;
	struct in6_addr in6;

	ns_tsig_key key;
	char *keyfile = NULL, *keyname = NULL;
	const char *pingfmt = NULL;

	UNUSED(argc);

	res_ninit(&res);
	res.pfcode = PRF_DEF;
	qtypeSet = 0;
	memset(domain, 0, sizeof domain);
	gethostname(myhostname, (sizeof myhostname));
#ifdef HAVE_SA_LEN
	myaddress.sin_len = sizeof(struct sockaddr_in);
#endif
	myaddress.sin_family = AF_INET;
	myaddress.sin_addr.s_addr = INADDR_ANY;
	myaddress.sin_port = 0; /*INPORT_ANY*/;

#ifdef HAVE_SA_LEN
	myaddress6.sin6_len = sizeof(struct sockaddr_in6);
#endif
	myaddress6.sin6_family = AF_INET6;
	myaddress6.sin6_addr = in6addr_any;
	myaddress6.sin6_port = 0; /*INPORT_ANY*/;

	res_x = res;

/*
 * If LOCALDEF in environment, should point to file
 * containing local favourite defaults.  Also look for file
 * DiG.env (i.e. SAVEENV) in local directory.
 */

	if ((((afile = (char *) getenv("LOCALDEF")) != (char *) NULL) &&
	     ((fp = open(afile, O_RDONLY)) > 0)) ||
	    ((fp = open(SAVEENV, O_RDONLY)) > 0)) {
		read(fp, (char *)&res_x, (sizeof res_x));
		close(fp);
		res = res_x;
	}
/*
 * Check for batch-mode DiG; also pre-scan for 'help'.
 */
	vtmp = argv;
	ax = args;
	while (*vtmp != NULL) {
		if (strcmp(*vtmp, "-h") == 0 ||
		    strcmp(*vtmp, "-help") == 0 ||
		    strcmp(*vtmp, "-usage") == 0 ||
		    strcmp(*vtmp, "help") == 0) {
			Usage();
			exit(0);
		}

		if (strcmp(*vtmp, "-f") == 0) {
			dofile++; once=0;
			if ((qfp = fopen(*++vtmp, "r")) == NULL) {
				fflush(stdout);
				perror("file open");
				fflush(stderr);
				exit(10);
			}
		} else {
			if (ax - args == DIG_MAXARGS) {
				fprintf(stderr, "dig: too many arguments\n");
				exit(10);
			}
			*ax++ = *vtmp;
		}
		vtmp++;
	}

	gettimeofday(&tv1, NULL);

/*
 * Main section: once if cmd-line query
 *               while !EOF if batch mode
 */
	*fileq = '\0';
	while ((dofile && fgets(fileq, sizeof fileq, qfp) != NULL) || 
	       (!dofile && once--)) 
	{
		if (*fileq == '\n' || *fileq == '#' || *fileq==';') {
			printf("%s", fileq);	/* echo but otherwise ignore */
			continue;		/* blank lines and comments  */
		}

/*
 * "Sticky" requests that before current parsing args
 * return to current "working" environment (X******).
 */
		if (sticky) {
			printf(";; (using sticky settings)\n");
			res = res_x;
		}

/*
 * Concat cmd-line and file args.
 */
		stackarg(fileq, ax);

		/* defaults */
		queryType = ns_t_ns;
		queryClass = ns_c_in;
		xfr = ns_t_invalid;
		*pingstr = 0;
		srv = NULL;

		sprintf(cmd, "\n; <<>> DiG %s (libbind %d) <<>> ",
			VSTRING, __RES);
		argv = args;
		/* argc = ax - args; */
/*
 * More cmd-line options than anyone should ever have to
 * deal with ....
 */
		while (*(++argv) != NULL && **argv != '\0') { 
			if (strlen(cmd) + strlen(*argv) + 2 > sizeof (cmd)) {
				fprintf(stderr,
				   "Argument too large for input buffer\n");
				exit(1);
			}
			strcat(cmd, *argv);
			strcat(cmd, " ");
			if (**argv == '@') {
				srv = (*argv+1);
				continue;
			}
			if (**argv == '%')
				continue;
			if (**argv == '+') {
				setopt(*argv+1);
				continue;
			}
			if (**argv == '=') {
				ixfr_serial = strtoul(*argv+1, NULL, 0);
				continue;
			}
			if (strncmp(*argv, "-nost", 5) == 0) {
				sticky = 0;
				continue;
			} else if (strncmp(*argv, "-st", 3) == 0) {
				sticky++;
				continue;
			} else if (strncmp(*argv, "-envsa", 6) == 0) {
				envsave++;
				continue;
			} else if (strncmp(*argv, "-envse", 6) == 0) {
				envset++;
				continue;
			}

			if (**argv == '-') {
				switch (argv[0][1]) { 
				case 'T':
					if (*++argv == NULL)
						printf("; no arg for -T?\n");
					else
						wait = atoi(*argv);
					break;
				case 'c': 
					if(*++argv == NULL) 
						printf("; no arg for -c?\n");
					else if ((tmp = atoi(*argv))
						  || *argv[0] == '0') {
						queryClass = tmp;
					} else if ((tmp = StringToClass(*argv,
								       0, NULL)
						   ) != 0) {
						queryClass = tmp;
					} else {
						printf(
						  "; invalid class specified\n"
						       );
					}
					break;
				case 't': 
					if (*++argv == NULL)
						printf("; no arg for -t?\n");
					else if ((tmp = atoi(*argv))
					    || *argv[0]=='0') {
						if (ns_t_xfr_p(tmp)) {
							xfr = tmp;
						} else {
							queryType = tmp;
							qtypeSet++;
						}
					} else if ((tmp = StringToType(*argv,
								      0, NULL)
						   ) != 0) {
						if (ns_t_xfr_p(tmp)) {
							xfr = tmp;
						} else {
							queryType = tmp;
							qtypeSet++;
						}
					} else {
						printf(
						   "; invalid type specified\n"
						       );
					}
					break;
				case 'x':
					if (!qtypeSet) {
						queryType = T_ANY;
						qtypeSet++;
					}
					if ((addrc = *++argv) == NULL) {
						printf("; no arg for -x?\n");
						break;
					}
					r = inet_pton(AF_INET6, addrc, &in6);
					if (r > 0) {
						reverse6(domain, &in6);
						break;
					}
					addrend = addrc + strlen(addrc);
					if (*addrend == '.')
						*addrend = '\0';
					*domain = '\0';
					while ((addrbegin = strrchr(addrc,'.'))) {
						strcat(domain, addrbegin+1);
						strcat(domain, ".");
						*addrbegin = '\0';
					}
					strcat(domain, addrc);
					strcat(domain, ".in-addr.arpa.");
					break;
				case 'p':
					if (argv[0][2] != '\0')
						port = htons(atoi(argv[0]+2));
					else if (*++argv == NULL)
						printf("; no arg for -p?\n");
					else
						port = htons(atoi(*argv));
					break;
				case 'P':
					if (argv[0][2] != '\0') {
						strcpy(pingstr, argv[0]+2);
						pingfmt =
							"%s %s 56 3 | %s -3";
					} else {
						strcpy(pingstr, DIG_PING);
						pingfmt = DIG_PINGFMT;
					}
					break;
				case 'n':
					if (argv[0][2] != '\0')
						res.ndots = atoi(argv[0]+2);
					else if (*++argv == NULL)
						printf("; no arg for -n?\n");
					else
						res.ndots = atoi(*argv);
					break;
				case 'b': {
					char *a, *p;

					if (argv[0][2] != '\0')
						a = argv[0]+2;
					else if (*++argv == NULL) {
						printf("; no arg for -b?\n");
						break;
					} else
						a = *argv;
					if ((p = strchr(a, ':')) != NULL) {
						*p++ = '\0';
						lport = htons(atoi(p));
					} else
						lport = htons(0);
					if (inet_pton(AF_INET6, a,
					      &myaddress6.sin6_addr) == 1) {
					      myaddress6.sin6_port = lport;
					} else if (!inet_aton(a,
						   &myaddress.sin_addr)) {
						fprintf(stderr,
							";; bad -b addr\n");
						exit(1);
					} else
						myaddress.sin_port = lport;
				    }
				    break;
				case 'k':
					/* -k keydir:keyname */
					
					if (argv[0][2] != '\0')
						keyfile = argv[0]+2;
					else if (*++argv == NULL) {
						printf("; no arg for -k?\n");
						break;
					} else
						keyfile = *argv;

					keyname = strchr(keyfile, ':');
					if (keyname == NULL) {
						fprintf(stderr,
			     "key option argument should be keydir:keyname\n");
						exit(1);
					}
					*keyname++='\0';
					break;
				} /* switch - */
				continue;
			} /* if '-'   */

			if ((tmp = StringToType(*argv, -1, NULL)) != -1) { 
				if ((T_ANY == tmp) && anyflag++) {  
					queryClass = C_ANY; 	
					continue; 
				}
				if (ns_t_xfr_p(tmp) &&
				    (tmp == ns_t_axfr ||
				     (res.options & RES_USEVC) != 0)
				     ) {
					res.pfcode = PRF_ZONE;
					xfr = (ns_type)tmp;
				} else {
					queryType = tmp; 
					qtypeSet++;
				}
			} else if ((tmp = StringToClass(*argv, -1, NULL))
				   != -1) { 
				queryClass = tmp; 
			} else {
				memset(domain, 0, sizeof domain);
				sprintf(domain,"%s",*argv);
			}
		} /* while argv remains */

		/* process key options */
		if (keyfile) {
#ifdef PARSE_KEYFILE
			int i, n1;
			char buf[BUFSIZ], *p;
			FILE *fp = NULL;
			int file_major, file_minor, alg;

			fp = fopen(keyfile, "r");
			if (fp == NULL) {
				perror(keyfile);
				exit(1);
			}
			/* Now read the header info from the file. */
			i = fread(buf, 1, BUFSIZ, fp);
			if (i < 5) {
				fclose(fp);
	                	exit(1);
	        	}
			fclose(fp);
	
			p = buf;
	
			n=strlen(p);		/* get length of strings */
			n1=strlen("Private-key-format: v");
			if (n1 > n ||
			    strncmp(buf, "Private-key-format: v", n1)) {
				fprintf(stderr, "Invalid key file format\n");
				exit(1);	/* not a match */
			}
			p+=n1;		/* advance pointer */
			sscanf((char *)p, "%d.%d", &file_major, &file_minor);
			/* should do some error checking with these someday */
			while (*p++!='\n');	/* skip to end of line */
	
	        	n=strlen(p);		/* get length of strings */
	        	n1=strlen("Algorithm: ");
	        	if (n1 > n || strncmp(p, "Algorithm: ", n1)) {
				fprintf(stderr, "Invalid key file format\n");
	                	exit(1);	/* not a match */
			}
			p+=n1;		/* advance pointer */
			if (sscanf((char *)p, "%d", &alg)!=1) {
				fprintf(stderr, "Invalid key file format\n");
				exit(1);
			}
			while (*p++!='\n');	/* skip to end of line */
	
	        	n=strlen(p);		/* get length of strings */
	        	n1=strlen("Key: ");
	        	if (n1 > n || strncmp(p, "Key: ", n1)) {
				fprintf(stderr, "Invalid key file format\n");
				exit(1);	/* not a match */
			}
			p+=n1;		/* advance pointer */
			pp=p;
			while (*pp++!='\n');	/* skip to end of line,
						 * terminate it */
			*--pp='\0';
	
			key.data=malloc(1024*sizeof(char));
			key.len=b64_pton(p, key.data, 1024);
	
			strcpy(key.name, keyname);
			strcpy(key.alg, "HMAC-MD5.SIG-ALG.REG.INT");
#else
			/* use the dst* routines to parse the key files
			 * 
			 * This requires that both the .key and the .private
			 * files exist in your cwd, so the keyfile parmeter
			 * here is assumed to be a path in which the
			 * K*.{key,private} files exist.
			 */
			DST_KEY *dst_key;
			char cwd[PATH_MAX+1];
	
			if (getcwd(cwd, PATH_MAX)==NULL) {
				perror("unable to get current directory");
				exit(1);
			}
			if (chdir(keyfile)<0) {
				fprintf(stderr,
					"unable to chdir to %s: %s\n", keyfile,
					strerror(errno));
				exit(1);
			}
	
			dst_init();
			dst_key = dst_read_key(keyname,
					       0 /* not used for priv keys */,
					       KEY_HMAC_MD5, DST_PRIVATE);
			if (!dst_key) {
				fprintf(stderr,
					"dst_read_key: error reading key\n");
				exit(1);
			}
			key.data=malloc(1024*sizeof(char));
			dst_key_to_buffer(dst_key, key.data, 1024);
			key.len=dst_key->dk_key_size;
	
			strcpy(key.name, keyname);
			strcpy(key.alg, "HMAC-MD5.SIG-ALG.REG.INT");
	
			if (chdir(cwd)<0) {
				fprintf(stderr, "unable to chdir to %s: %s\n",
					cwd, strerror(errno));
				exit(1);
			}
#endif
		}

		if (res.pfcode & 0x80000)
			printf("; pfcode: %08lx, options: %08lx\n",
			       (unsigned long)res.pfcode,
			       (unsigned long)res.options);
	  
/*
 * Current env. (after this parse) is to become the
 * new "working" environmnet. Used in conj. with sticky.
 */
		if (envset) {
			res_x = res;
			envset = 0;
		}

/*
 * Current env. (after this parse) is to become the
 * new default saved environmnet. Save in user specified
 * file if exists else is SAVEENV (== "DiG.env").
 */
		if (envsave) {
			afile = (char *) getenv("LOCALDEF");
			if ((afile &&
			     ((fp = open(afile,
					 O_WRONLY|O_CREAT|O_TRUNC,
					 S_IREAD|S_IWRITE)) > 0))
			    ||
			    ((fp = open(SAVEENV,
					O_WRONLY|O_CREAT|O_TRUNC,
					S_IREAD|S_IWRITE)) > 0)) {
				write(fp, (char *)&res, (sizeof res));
				close(fp);
			}
			envsave = 0;
		}

		if (res.pfcode & RES_PRF_CMD)
			printf("%s\n", cmd);

		anyflag = 0;

/*
 * Find address of server to query. If not dot-notation, then
 * try to resolve domain-name (if so, save and turn off print 
 * options, this domain-query is not the one we want. Restore
 * user options when done.
 * Things get a bit wierd since we need to use resolver to be
 * able to "put the resolver to work".
 */

		if (srv != NULL) {
			int nscount = 0;
			union res_sockaddr_union u[MAXNS];
			struct addrinfo *answer = NULL;
			struct addrinfo *cur = NULL;
			struct addrinfo hint;

			memset(u, 0, sizeof(u));
			res_t = res;
			res_ninit(&res);
			res.pfcode = 0;
			res.options = RES_DEFAULT;
			memset(&hint, 0, sizeof(hint));
			hint.ai_socktype = SOCK_DGRAM;
			if (!getaddrinfo(srv, NULL, &hint, &answer)) {
				res = res_t;
				cur = answer;
				for (cur = answer;
				     cur != NULL;
				     cur = cur->ai_next) {
					if (nscount == MAXNS)
						break;
					switch (cur->ai_addr->sa_family) {
					case AF_INET6:
						u[nscount].sin6 =
					  *(struct sockaddr_in6*)cur->ai_addr;
						u[nscount++].sin6.sin6_port =
							port;
						break;
					case AF_INET:
						u[nscount].sin =
					   *(struct sockaddr_in*)cur->ai_addr;
						u[nscount++].sin.sin_port =
							port;
						break;
					}
				}
				if (nscount != 0)
					res_setservers(&res, u, nscount);
				freeaddrinfo(answer);
			} else {
				res = res_t;
				fflush(stdout);
				fprintf(stderr,
		"; Bad server: %s -- using default server and timer opts\n",
						srv);
				fflush(stderr);
				srv = NULL;
			}
			printf("; (%d server%s found)\n",
			       res.nscount, (res.nscount==1)?"":"s");
			res.id += res.retry;
		}

		if (ns_t_xfr_p(xfr)) {
			int i;
			int nscount;
			union res_sockaddr_union u[MAXNS];
			nscount = res_getservers(&res, u, MAXNS);
			for (i = 0; i < nscount; i++) {
				int x;

				if (keyfile)
					x = printZone(xfr, domain,
						      &u[i].sin,
						      &key);
				else
					x = printZone(xfr, domain,
						      &u[i].sin,
						      NULL);
				if (res.pfcode & RES_PRF_STATS) {
					exectime = time(NULL);
					printf(";; FROM: %s to SERVER: %s\n",
					       myhostname,
					       p_sockun(u[i], ubuf,
							sizeof(ubuf)));
					printf(";; WHEN: %s", ctime(&exectime));
				}
				if (!x)
					break;	/* success */
			}
			fflush(stdout);
			continue;
		}

		if (*domain && !qtypeSet) {
			queryType = T_A;
			qtypeSet++;
		}
		
		bytes_out = n = res_nmkquery(&res, QUERY, domain,
					     queryClass, queryType,
					     NULL, 0, NULL,
					     packet, sizeof packet);
		if (n < 0) {
			fflush(stderr);
			printf(";; res_nmkquery: buffer too small\n\n");
			fflush(stdout);
			continue;
		}
		if (queryType == T_IXFR) {
			HEADER *hp = (HEADER *) packet;
			u_char *cpp = packet + bytes_out;

			hp->nscount = htons(1+ntohs(hp->nscount));
			n = dn_comp(domain, cpp,
				    (sizeof packet) - (cpp - packet),
				    NULL, NULL);
			cpp += n;
			PUTSHORT(T_SOA, cpp); /* type */
			PUTSHORT(C_IN, cpp);  /* class */
			PUTLONG(0, cpp);      /* ttl */
			PUTSHORT(22, cpp);    /* dlen */
			*cpp++ = 0;           /* mname */
			*cpp++ = 0;           /* rname */
			PUTLONG(ixfr_serial, cpp);
			PUTLONG(0xDEAD, cpp); /* Refresh */
			PUTLONG(0xBEEF, cpp); /* Retry */
			PUTLONG(0xABCD, cpp); /* Expire */
			PUTLONG(0x1776, cpp); /* Min TTL */
			bytes_out = n = cpp - packet;
		};	

#if defined(RES_USE_EDNS0) && defined(RES_USE_DNSSEC)
		if (n > 0 &&
		    (res.options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0)
			bytes_out = n = res_nopt(&res, n, packet,
						 sizeof(packet), 4096);
#endif

		eecode = 0;
		if (res.pfcode & RES_PRF_HEAD1)
			fp_resstat(&res, stdout);
		(void) gettimeofday(&start_time, NULL);
		if (keyfile)
			n = res_nsendsigned(&res, packet, n, &key,
					    answer.b, sizeof(answer.b));
		else
			n = res_nsend(&res, packet, n,
				      answer.b, sizeof(answer.b));
		if ((bytes_in = n) < 0) {
			fflush(stdout);
			n = 0 - n;
			if (keyfile)
				strcpy(msg, ";; res_nsendsigned");
			else
				strcpy(msg, ";; res_nsend");
			perror(msg);
			fflush(stderr);

			if (!dofile) {
				if (eecode)
					exit(eecode);
				else
					exit(9);
			}
		}
		(void) gettimeofday(&end_time, NULL);

		if (res.pfcode & RES_PRF_STATS) {
			union res_sockaddr_union u[MAXNS];

			(void) res_getservers(&res, u, MAXNS);
			query_time = difftv(start_time, end_time);
			printf(";; Total query time: ");
			prnttime(query_time);
			putchar('\n');
			exectime = time(NULL);
			printf(";; FROM: %s to SERVER: %s\n", myhostname,
			       p_sockun(u[RES_GETLAST(res)],
					ubuf, sizeof(ubuf)));
			printf(";; WHEN: %s", ctime(&exectime));
			printf(";; MSG SIZE  sent: %d  rcvd: %d\n",
			       bytes_out, bytes_in);
		}
	  
		fflush(stdout);
/*
 *   Argh ... not particularly elegant. Should put in *real* ping code.
 *   Would necessitate root priviledges for icmp port though!
 */
		if (*pingstr && srv != NULL) {
			sprintf(doping, pingfmt, pingstr, srv, DIG_TAIL);
			system(doping);
		}
		putchar('\n');

/*
 * Fairly crude method and low overhead method of keeping two
 * batches started at different sites somewhat synchronized.
 */
		gettimeofday(&tv2, NULL);
		delay = (int)(tv2.tv_sec - tv1.tv_sec);
		if (delay < wait) {
			sleep(wait - delay);
		}
		tv1 = tv2;
	}
	return (eecode);
}
Beispiel #30
0
/*%
 * Form update packets.
 * Returns the size of the resulting packet if no error
 *
 * On error,
 *	returns 
 *\li              -1 if error in reading a word/number in rdata
 *		   portion for update packets
 *\li		-2 if length of buffer passed is insufficient
 *\li		-3 if zone section is not the first section in
 *		   the linked list, or section order has a problem
 *\li		-4 on a number overflow
 *\li		-5 unknown operation or no records
 */
int
res_nmkupdate(res_state statp, ns_updrec *rrecp_in, u_char *buf, int buflen) {
	ns_updrec *rrecp_start = rrecp_in;
	HEADER *hp;
	u_char *cp, *sp2, *startp, *endp;
	int n, i, soanum, multiline;
	ns_updrec *rrecp;
	struct in_addr ina;
	struct in6_addr in6a;
        char buf2[MAXDNAME];
	u_char buf3[MAXDNAME];
	int section, numrrs = 0, counts[ns_s_max];
	u_int16_t rtype, rclass;
	u_int32_t n1, rttl;
	u_char *dnptrs[20], **dpp, **lastdnptr;
	int siglen, keylen, certlen;

	/*
	 * Initialize header fields.
	 */
	if ((buf == NULL) || (buflen < HFIXEDSZ))
		return (-1);
	memset(buf, 0, HFIXEDSZ);
	hp = (HEADER *) buf;
	hp->id = htons(++statp->id);
	hp->opcode = ns_o_update;
	hp->rcode = NOERROR;
	cp = buf + HFIXEDSZ;
	buflen -= HFIXEDSZ;
	dpp = dnptrs;
	*dpp++ = buf;
	*dpp++ = NULL;
	lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];

	if (rrecp_start == NULL)
		return (-5);
	else if (rrecp_start->r_section != S_ZONE)
		return (-3);

	memset(counts, 0, sizeof counts);
	for (rrecp = rrecp_start; rrecp; rrecp = NEXT(rrecp, r_glink)) {
		numrrs++;
                section = rrecp->r_section;
		if (section < 0 || section >= ns_s_max)
			return (-1);
		counts[section]++;
		for (i = section + 1; i < ns_s_max; i++)
			if (counts[i])
				return (-3);
		rtype = rrecp->r_type;
		rclass = rrecp->r_class;
		rttl = rrecp->r_ttl;
		/* overload class and type */
		if (section == S_PREREQ) {
			rttl = 0;
			switch (rrecp->r_opcode) {
			case YXDOMAIN:
				rclass = C_ANY;
				rtype = T_ANY;
				rrecp->r_size = 0;
				break;
			case NXDOMAIN:
				rclass = C_NONE;
				rtype = T_ANY;
				rrecp->r_size = 0;
				break;
			case NXRRSET:
				rclass = C_NONE;
				rrecp->r_size = 0;
				break;
			case YXRRSET:
				if (rrecp->r_size == 0)
					rclass = C_ANY;
				break;
			default:
				fprintf(stderr,
					"res_mkupdate: incorrect opcode: %d\n",
					rrecp->r_opcode);
				fflush(stderr);
				return (-1);
			}
		} else if (section == S_UPDATE) {
			switch (rrecp->r_opcode) {
			case DELETE:
				rclass = rrecp->r_size == 0 ? C_ANY : C_NONE;
				break;
			case ADD:
				break;
			default:
				fprintf(stderr,
					"res_mkupdate: incorrect opcode: %d\n",
					rrecp->r_opcode);
				fflush(stderr);
				return (-1);
			}
		}

		/*
		 * XXX	appending default domain to owner name is omitted,
		 *	fqdn must be provided
		 */
		if ((n = dn_comp(rrecp->r_dname, cp, buflen, dnptrs,
				 lastdnptr)) < 0)
			return (-1);
		cp += n;
		ShrinkBuffer(n + 2*INT16SZ);
		PUTSHORT(rtype, cp);
		PUTSHORT(rclass, cp);
		if (section == S_ZONE) {
			if (numrrs != 1 || rrecp->r_type != T_SOA)
				return (-3);
			continue;
		}
		ShrinkBuffer(INT32SZ + INT16SZ);
		PUTLONG(rttl, cp);
		sp2 = cp;  /*%< save pointer to length byte */
		cp += INT16SZ;
		if (rrecp->r_size == 0) {
			if (section == S_UPDATE && rclass != C_ANY)
				return (-1);
			else {
				PUTSHORT(0, sp2);
				continue;
			}
		}
		startp = rrecp->r_data;
		endp = startp + rrecp->r_size - 1;
		/* XXX this should be done centrally. */
		switch (rrecp->r_type) {
		case T_A:
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			if (!inet_aton(buf2, &ina))
				return (-1);
			n1 = ntohl(ina.s_addr);
			ShrinkBuffer(INT32SZ);
			PUTLONG(n1, cp);
			break;
		case T_CNAME:
		case T_MB:
		case T_MG:
		case T_MR:
		case T_NS:
		case T_PTR:
		case ns_t_dname:
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			break;
		case T_MINFO:
		case T_SOA:
		case T_RP:
			for (i = 0; i < 2; i++) {
				if (!getword_str(buf2, sizeof buf2, &startp,
						 endp))
				return (-1);
				n = dn_comp(buf2, cp, buflen,
					    dnptrs, lastdnptr);
				if (n < 0)
					return (-1);
				cp += n;
				ShrinkBuffer(n);
			}
			if (rrecp->r_type == T_SOA) {
				ShrinkBuffer(5 * INT32SZ);
				while (isspace(*startp) || !*startp)
					startp++;
				if (*startp == '(') {
					multiline = 1;
					startp++;
				} else
					multiline = 0;
				/* serial, refresh, retry, expire, minimum */
				for (i = 0; i < 5; i++) {
					soanum = getnum_str(&startp, endp);
					if (soanum < 0)
						return (-1);
					PUTLONG(soanum, cp);
				}
				if (multiline) {
					while (isspace(*startp) || !*startp)
						startp++;
					if (*startp != ')')
						return (-1);
				}
			}
			break;
		case T_MX:
		case T_AFSDB:
		case T_RT:
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			break;
		case T_SRV:
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);

			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);

			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);

			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, NULL, NULL);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			break;
		case T_PX:
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			PUTSHORT(n, cp);
			ShrinkBuffer(INT16SZ);
			for (i = 0; i < 2; i++) {
				if (!getword_str(buf2, sizeof buf2, &startp,
						 endp))
					return (-1);
				n = dn_comp(buf2, cp, buflen, dnptrs,
					    lastdnptr);
				if (n < 0)
					return (-1);
				cp += n;
				ShrinkBuffer(n);
			}
			break;
		case T_WKS: {
			char bm[MAXPORT/8];
			unsigned int maxbm = 0;

			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			if (!inet_aton(buf2, &ina))
				return (-1);
			n1 = ntohl(ina.s_addr);
			ShrinkBuffer(INT32SZ);
			PUTLONG(n1, cp);

			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			if ((i = res_protocolnumber(buf2)) < 0)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = i & 0xff;
			 
			for (i = 0; i < MAXPORT/8 ; i++)
				bm[i] = 0;

			while (getword_str(buf2, sizeof buf2, &startp, endp)) {
				if ((n = res_servicenumber(buf2)) <= 0)
					return (-1);

				if (n < MAXPORT) {
					bm[n/8] |= (0x80>>(n%8));
					if ((unsigned)n > maxbm)
						maxbm = n;
				} else
					return (-1);
			}
			maxbm = maxbm/8 + 1;
			ShrinkBuffer(maxbm);
			memcpy(cp, bm, maxbm);
			cp += maxbm;
			break;
		}
		case T_HINFO:
			for (i = 0; i < 2; i++) {
				if ((n = getstr_str(buf2, sizeof buf2,
						&startp, endp)) < 0)
					return (-1);
				if (n > 255)
					return (-1);
				ShrinkBuffer(n+1);
				*cp++ = n;
				memcpy(cp, buf2, n);
				cp += n;
			}
			break;
		case T_TXT:
			for (;;) {
				if ((n = getstr_str(buf2, sizeof buf2,
						&startp, endp)) < 0) {
					if (cp != (sp2 + INT16SZ))
						break;
					return (-1);
				}
				if (n > 255)
					return (-1);
				ShrinkBuffer(n+1);
				*cp++ = n;
				memcpy(cp, buf2, n);
				cp += n;
			}
			break;
		case T_X25:
			/* RFC1183 */
			if ((n = getstr_str(buf2, sizeof buf2, &startp,
					 endp)) < 0)
				return (-1);
			if (n > 255)
				return (-1);
			ShrinkBuffer(n+1);
			*cp++ = n;
			memcpy(cp, buf2, n);
			cp += n;
			break;
		case T_ISDN:
			/* RFC1183 */
			if ((n = getstr_str(buf2, sizeof buf2, &startp,
					 endp)) < 0)
				return (-1);
			if ((n > 255) || (n == 0))
				return (-1);
			ShrinkBuffer(n+1);
			*cp++ = n;
			memcpy(cp, buf2, n);
			cp += n;
			if ((n = getstr_str(buf2, sizeof buf2, &startp,
					 endp)) < 0)
				n = 0;
			if (n > 255)
				return (-1);
			ShrinkBuffer(n+1);
			*cp++ = n;
			memcpy(cp, buf2, n);
			cp += n;
			break;
		case T_NSAP:
			if ((n = inet_nsap_addr((char *)startp, (u_char *)buf2, sizeof(buf2))) != 0) {
				ShrinkBuffer(n);
				memcpy(cp, buf2, n);
				cp += n;
			} else {
				return (-1);
			}
			break;
		case T_LOC:
			if ((n = loc_aton((char *)startp, (u_char *)buf2)) != 0) {
				ShrinkBuffer(n);
				memcpy(cp, buf2, n);
				cp += n;
			} else
				return (-1);
			break;
		case ns_t_sig:
		    {
			int sig_type, success, dateerror;
			u_int32_t exptime, timesigned;

			/* type */
			if ((n = getword_str(buf2, sizeof buf2,
					     &startp, endp)) < 0)
				return (-1);
			sig_type = sym_ston(__p_type_syms, buf2, &success);
			if (!success || sig_type == ns_t_any)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(sig_type, cp);
			/* alg */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = n;
			/* labels */
			n = getnum_str(&startp, endp);
			if (n <= 0 || n > 255)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = n;
			/* ottl  & expire */
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			exptime = ns_datetosecs(buf2, &dateerror);
			if (!dateerror) {
				ShrinkBuffer(INT32SZ);
				PUTLONG(rttl, cp);
			}
			else {
				char *ulendp;
				u_int32_t ottl;

				errno = 0;
				ottl = strtoul(buf2, &ulendp, 10);
				if (errno != 0 ||
				    (ulendp != NULL && *ulendp != '\0'))
					return (-1);
				ShrinkBuffer(INT32SZ);
				PUTLONG(ottl, cp);
				if (!getword_str(buf2, sizeof buf2, &startp,
						 endp))
					return (-1);
				exptime = ns_datetosecs(buf2, &dateerror);
				if (dateerror)
					return (-1);
			}
			/* expire */
			ShrinkBuffer(INT32SZ);
			PUTLONG(exptime, cp);
			/* timesigned */
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			timesigned = ns_datetosecs(buf2, &dateerror);
			if (!dateerror) {
				ShrinkBuffer(INT32SZ);
				PUTLONG(timesigned, cp);
			}
			else
				return (-1);
			/* footprint */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);
			/* signer name */
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			/* sig */
			if ((n = getword_str(buf2, sizeof buf2,
					     &startp, endp)) < 0)
				return (-1);
			siglen = b64_pton(buf2, buf3, sizeof(buf3));
			if (siglen < 0)
				return (-1);
			ShrinkBuffer(siglen);
			memcpy(cp, buf3, siglen);
			cp += siglen;
			break;
		    }
		case ns_t_key:
			/* flags */
			n = gethexnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);
			/* proto */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = n;
			/* alg */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = n;
			/* key */
			if ((n = getword_str(buf2, sizeof buf2,
					     &startp, endp)) < 0)
				return (-1);
			keylen = b64_pton(buf2, buf3, sizeof(buf3));
			if (keylen < 0)
				return (-1);
			ShrinkBuffer(keylen);
			memcpy(cp, buf3, keylen);
			cp += keylen;
			break;
		case ns_t_nxt:
		    {
			int success, nxt_type;
			u_char data[32];
			int maxtype;

			/* next name */
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, NULL, NULL);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			maxtype = 0;
			memset(data, 0, sizeof data);
			for (;;) {
				if (!getword_str(buf2, sizeof buf2, &startp,
						 endp))
					break;
				nxt_type = sym_ston(__p_type_syms, buf2,
						    &success);
				if (!success || !ns_t_rr_p(nxt_type))
					return (-1);
				NS_NXT_BIT_SET(nxt_type, data);
				if (nxt_type > maxtype)
					maxtype = nxt_type;
			}
			n = maxtype/NS_NXT_BITS+1;
			ShrinkBuffer(n);
			memcpy(cp, data, n);
			cp += n;
			break;
		    }
		case ns_t_cert:
			/* type */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);
			/* key tag */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);
			/* alg */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = n;
			/* cert */
			if ((n = getword_str(buf2, sizeof buf2,
					     &startp, endp)) < 0)
				return (-1);
			certlen = b64_pton(buf2, buf3, sizeof(buf3));
			if (certlen < 0)
				return (-1);
			ShrinkBuffer(certlen);
			memcpy(cp, buf3, certlen);
			cp += certlen;
			break;
		case ns_t_aaaa:
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			if (inet_pton(AF_INET6, buf2, &in6a) <= 0)
				return (-1);
			ShrinkBuffer(NS_IN6ADDRSZ);
			memcpy(cp, &in6a, NS_IN6ADDRSZ);
			cp += NS_IN6ADDRSZ;
			break;
		case ns_t_naptr:
			/* Order Preference Flags Service Replacement Regexp */
			/* Order */
			n = getnum_str(&startp, endp);
			if (n < 0 || n > 65535)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);
			/* Preference */
			n = getnum_str(&startp, endp);
			if (n < 0 || n > 65535)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);
			/* Flags */
			if ((n = getstr_str(buf2, sizeof buf2,
					&startp, endp)) < 0) {
				return (-1);
			}
			if (n > 255)
				return (-1);
			ShrinkBuffer(n+1);
			*cp++ = n;
			memcpy(cp, buf2, n);
			cp += n;
			/* Service Classes */
			if ((n = getstr_str(buf2, sizeof buf2,
					&startp, endp)) < 0) {
				return (-1);
			}
			if (n > 255)
				return (-1);
			ShrinkBuffer(n+1);
			*cp++ = n;
			memcpy(cp, buf2, n);
			cp += n;
			/* Pattern */
			if ((n = getstr_str(buf2, sizeof buf2,
					&startp, endp)) < 0) {
				return (-1);
			}
			if (n > 255)
				return (-1);
			ShrinkBuffer(n+1);
			*cp++ = n;
			memcpy(cp, buf2, n);
			cp += n;
			/* Replacement */
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, NULL, NULL);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			break;
		default:
			return (-1);
		} /*switch*/