void extract_headers (GMimeMessage *message, GMimeStream *out_stream) { const char *subject; char *escaped_subject; const char *sender; char *escaped_sender; const char *reply_to; char *escaped_reply_to; time_t t; int tz; char buf[64]; struct tm *t_m; subject = g_mime_message_get_subject(message); escaped_subject = str_replace((char *) subject, "\"", ""); g_mime_stream_printf (out_stream, "subject: \"%s\", ", escaped_subject); g_mime_stream_printf (out_stream, "message_id: \"%s\", ", g_mime_message_get_message_id(message)); sender = g_mime_message_get_sender(message); escaped_sender = str_replace((char *) sender, "\"", ""); g_mime_stream_printf (out_stream, "sender: \"%s\", ", escaped_sender); reply_to = g_mime_message_get_reply_to(message); escaped_reply_to = str_replace((char *) reply_to, "\"", ""); g_mime_stream_printf (out_stream, "reply_to: \"%s\", ", escaped_reply_to); g_mime_message_get_date (message, &t, &tz); t_m = localtime (&t); strftime(buf, sizeof(buf) - 1, "%c", t_m); g_mime_stream_printf (out_stream, "date: \"%s\", ", buf); strftime(buf, sizeof(buf) - 1, "%Y%m%d%H%M%S", t_m); g_mime_stream_printf (out_stream, "sort_date: \"%s\", ", buf); InternetAddressList *recipients; recipients = g_mime_message_get_recipients(message, GMIME_RECIPIENT_TYPE_TO); g_mime_stream_printf (out_stream, "recipients_to: ["); extract_addresses(recipients, out_stream); g_mime_stream_printf (out_stream, "], "); recipients = g_mime_message_get_recipients(message, GMIME_RECIPIENT_TYPE_CC); g_mime_stream_printf (out_stream, "recipients_cc: ["); extract_addresses(recipients, out_stream); g_mime_stream_printf (out_stream, "], "); recipients = g_mime_message_get_recipients(message, GMIME_RECIPIENT_TYPE_BCC); g_mime_stream_printf (out_stream, "recipients_bcc: ["); extract_addresses(recipients, out_stream); g_mime_stream_printf (out_stream, "] "); }
/* Extracts the mac, IPv4 and IPv6 addresses from * 'address' which * should be of the format 'MAC [IP1 IP2 ..]" where IPn should be a * valid IPv4 or IPv6 address and stores them in the 'ipv4_addrs' and * 'ipv6_addrs' fields of 'laddrs'. * * Return true if at least 'MAC' is found in 'address', false otherwise. * * The caller must call destroy_lport_addresses(). */ bool extract_lsp_addresses(const char *address, struct lport_addresses *laddrs) { int ofs; bool success = extract_addresses(address, laddrs, &ofs); if (success && ofs < strlen(address)) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); VLOG_INFO_RL(&rl, "invalid syntax '%s' in address", address); } return success; }
static size_t process_reply(HEADER *header, time_t now, struct server *server, size_t n) { unsigned char *pheader, *sizep; int munged = 0, is_sign; size_t plen; /* If upstream is advertising a larger UDP packet size than we allow, trim it so that we don't get overlarge requests for the client. We can't do this for signed packets. */ if ((pheader = find_pseudoheader(header, n, &plen, &sizep, &is_sign)) && !is_sign) { unsigned short udpsz; unsigned char *psave = sizep; GETSHORT(udpsz, sizep); if (udpsz > daemon->edns_pktsz) PUTSHORT(daemon->edns_pktsz, psave); } if (header->opcode != QUERY || (header->rcode != NOERROR && header->rcode != NXDOMAIN)) return n; /* Complain loudly if the upstream server is non-recursive. */ if (!header->ra && header->rcode == NOERROR && ntohs(header->ancount) == 0 && server && !(server->flags & SERV_WARNED_RECURSIVE)) { prettyprint_addr(&server->addr, daemon->namebuff); my_syslog(LOG_WARNING, _("nameserver %s refused to do a recursive query"), daemon->namebuff); if (!(daemon->options & OPT_LOG)) server->flags |= SERV_WARNED_RECURSIVE; } if (daemon->bogus_addr && header->rcode != NXDOMAIN && check_for_bogus_wildcard(header, n, daemon->namebuff, daemon->bogus_addr, now)) { munged = 1; header->rcode = NXDOMAIN; header->aa = 0; } else { if (header->rcode == NXDOMAIN && extract_request(header, n, daemon->namebuff, NULL) && check_for_local_domain(daemon->namebuff, now)) { /* if we forwarded a query for a locally known name (because it was for an unknown type) and the answer is NXDOMAIN, convert that to NODATA, since we know that the domain exists, even if upstream doesn't */ munged = 1; header->aa = 1; header->rcode = NOERROR; } if (extract_addresses(header, n, daemon->namebuff, now)) { my_syslog(LOG_WARNING, _("possible DNS-rebind attack detected")); munged = 1; } } /* do this after extract_addresses. Ensure NODATA reply and remove nameserver info. */ if (munged) { header->ancount = htons(0); header->nscount = htons(0); header->arcount = htons(0); } /* the bogus-nxdomain stuff, doctor and NXDOMAIN->NODATA munging can all elide sections of the packet. Find the new length here and put back pseudoheader if it was removed. */ return resize_packet(header, n, pheader, plen); }
/* returns new last_server */ struct server *reply_query(int fd, char *packet, char *dnamebuff, struct server *last_server,unsigned long *timetolive) { /* packet from peer server, extract data for cache, and send to original requester */ struct frec *forward; HEADER *header; int n = recv(fd, packet, PACKETSZ, 0); header = (HEADER *)packet; if (n >= (int)sizeof(HEADER) && header->qr) { if ((forward = lookup_frec(ntohs(header->id)))) { //if (header->rcode == NOERROR || header->rcode == NXDOMAIN) if (header->rcode == NOERROR) { /* ******* zg porting DWG814I Source code on 2006.11.06 ******* */ /* ******* To fixed cdrouterv3.3 item 333(dna_45) item 334(dns_45) failed bug ******* */ if(forward ->dnsMsgBufPtr != NULL) { free_dns_msg_buf(forward ->dnsMsgBufPtr); forward ->dnsMsgBufPtr = NULL; } /* ******* end by zg porting DWG814I Source code on 2006.11.06 ******* */ if (!forward->sentto->domain) last_server = forward->sentto; /* known good */ if (header->opcode == QUERY) { strncpy(query_name, dnamebuff, sizeof(query_name)); extract_addresses(header, (unsigned int)n, dnamebuff, timetolive); } header->id = htons(forward->orig_id); /* There's no point returning an upstream reply marked as truncated, since that will prod the resolver into moving to TCP - which we don't support. */ header->tc = 0; /* goodbye truncate */ sendto(forward->fd, packet, n, 0, &forward->source.sa, sa_len(&forward->source)); forward->new_id = 0; /* cancel */ } /* ******* zg porting DWG814I Source code on 2006.11.06 ******* */ /* ******* To fixed cdrouterv3.3 item 333(dna_45) item 334(dns_45) failed bug ******* */ else switch(header->rcode) { case SERVFAIL: case NOTIMP: case REFUSED: //DBG_printf("SERVER fail, not implement, refuse, try next server\n"); break; default: //DBG_printf("SERVER response general error, return it to client\n"); if(forward ->dnsMsgBufPtr != NULL) { free_dns_msg_buf(forward ->dnsMsgBufPtr); forward ->dnsMsgBufPtr = NULL; } header->id = htons(forward->orig_id); /* There's no point returning an upstream reply marked as truncated, since that will prod the resolver into moving to TCP - which we don't support. */ header->tc = 0; /* goodbye truncate */ sendto(forward->fd, packet, n, 0, &forward->source.sa, sa_len(&forward->source)); forward->new_id = 0; /* cancel */ break; } /* ******* end by zg porting DWG814I Source code on 2006.11.06 ******* */ } } return last_server; }