*** /tmp/,RCSt1014061 Tue Dec 20 19:13:27 1988 --- ns_req.c Tue Dec 20 18:06:48 1988 *************** *** 15,24 **** --- 15,29 ---- #include #include #include + #include + #include + #include #include "ns.h" #include "db.h" #define NADDRECS 20 + #define T_CRED 105 + #define TM_OFFSET 2208988800 struct addinfo { char *a_dname; /* domain name */ *************** *** 50,56 **** struct hashbuf *htp; struct zoneinfo *zp; char *fname; ! char dnbuf[MAXDNAME], *dname; char **dpp; char *dnp; char *newmsg; --- 55,61 ---- struct hashbuf *htp; struct zoneinfo *zp; char *fname; ! char dnbuf[MAXDNAME], *dname, myinst[INST_SZ]; char **dpp; char *dnp; char *newmsg; *************** *** 60,65 **** --- 65,72 ---- struct databuf *nsp[MAXNS], **nspp; struct qinfo *qp; time_t curtime; + AUTH_DAT auth; + int authenticated = 0; extern struct qinfo *qhead; extern int nsid; *************** *** 82,92 **** *dpp++ = msg; addcount = 0; - switch (hp->opcode) { case QUERY: if (ntohs(hp->qdcount) != 1 || ! hp->ancount || hp->nscount || hp->arcount) { #ifdef DEBUG if (debug) fprintf(ddt,"FORMERR Query header counts wrong\n"); --- 89,98 ---- *dpp++ = msg; addcount = 0; switch (hp->opcode) { case QUERY: if (ntohs(hp->qdcount) != 1 || ! hp->ancount || hp->nscount) { #ifdef DEBUG if (debug) fprintf(ddt,"FORMERR Query header counts wrong\n"); *************** *** 119,130 **** --- 125,210 ---- class = getshort(cp); cp += sizeof(u_short); if (cp < msg + msglen) { + if (hp->arcount) { + char *p; + KTEXT_ST cred; + C_Block bcksum[2]; + u_long cksum; + int err = 0; + + gethostname(myinst, sizeof(myinst)); + for (p = myinst; *p; p++) { + if (*p == '.') + *p = 0; + else if (isupper(*p)) + *p = tolower(*p); + } + + /* get kerberos ticket */ + p = cp + dn_skip(cp); + if (getshort(p) != T_CRED) + err++; + p += sizeof(u_short); + /* don't bother with CLASS */ + p += sizeof(u_short); + if (!err) { + p += sizeof(u_long); + cred.length = getshort(p); + p += sizeof(u_short); + bcopy(p, cred.dat, cred.length); + err = krb_rd_req(&cred, "hesiod", myinst, + from->sin_addr, &auth, ""); #ifdef DEBUG + if (err == RD_AP_BADD && debug) { + fprintf(ddt, "from->sin_addr = %s, ", + inet_ntoa(from->sin_addr)); + fprintf(ddt, "auth.address = %s\n", + inet_ntoa(auth.address)); + } + #endif + if (err != KSUCCESS) { + #ifdef DEBUG + if (debug) + fprintf(ddt,"kerberos error %d\n", err); + #endif + } else { + bzero(bcksum, sizeof(bcksum)); + cksum = quad_cksum((char *)hp, bcksum, + p-(char *)hp-sizeof(u_short), + 2, auth.session); + if (cksum != auth.checksum) { + #ifdef DEBUG + if (debug) + fprintf(ddt,"crypto checsum failed\n"); + #endif + } else { + authenticated++; + hp->arcount = 0; + #ifdef DEBUG + if (debug) + fprintf(ddt, + "kerberos authenticated %s%s%s@%s\n", + auth.pname, auth.pinst[0] == 0 ?"":".", + auth.pinst, auth.prealm); + #endif + } + } + } else { + #ifdef DEBUG + if (debug) + fprintf(ddt,"kerberos parse error\n"); + #endif + hp->rcode = FORMERR; + break; + } + } else { + #ifdef DEBUG if (debug) fprintf(ddt,"FORMERR Query message length off\n"); #endif hp->rcode = FORMERR; break; + } } #ifdef DEBUG if (cp > msg + msglen) *************** *** 763,768 **** --- 843,869 ---- hp->ra = 1; /* Recursion is Available */ if (addcount) cp += doaddinfo(hp, cp, buflen - (cp - msg)); + if (authenticated) { + C_Block bcksum[2]; + u_long cksum, curtime; + + hp->arcount = htons(1 + htons(hp->arcount)); + *cp++ = 0; + putshort(T_CRED, cp); + cp += sizeof(u_short); + putshort(C_HESIOD, cp); + cp += sizeof(u_short); + curtime =(u_long) tt.tv_sec + TM_OFFSET; + putlong(curtime, cp); + cp += sizeof(u_long); + bzero(bcksum, sizeof(bcksum)); + cksum = quad_cksum((char *)hp, bcksum, cp - (char *)hp, 2, + auth.session); + putshort(sizeof(cksum), cp); + cp += sizeof(u_short); + bcopy(&cksum, cp, sizeof(cksum)); + cp += sizeof(cksum); + } #ifdef DEBUG if (debug >= 10) fp_query(msg, ddt);