From af6d5f438bf18c92730a8ae273efa54cd11f2906 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Sun, 5 Nov 2017 15:42:31 +0100 Subject: ripe-atlas-fw: imported version 4780 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bjørn Mork --- eperd/evtdig.c | 141 ++++++++++++++++++++++++++++++----------------- eperd/ping.c | 82 +++++++++++++++++++++++---- eperd/sslgetcert.c | 82 ++++++++++++++++++++++++--- include/libbb.h | 1 + libbb/Kbuild | 1 + libbb/atlas_name_macro.c | 87 +++++++++++++++++++++++++++++ libbb/atlas_probe.c | 6 +- shell/hush.c | 12 ++++ 8 files changed, 341 insertions(+), 71 deletions(-) create mode 100644 libbb/atlas_name_macro.c diff --git a/eperd/evtdig.c b/eperd/evtdig.c index e25ad7a..39c868d 100644 --- a/eperd/evtdig.c +++ b/eperd/evtdig.c @@ -291,6 +291,7 @@ struct query_state { u_int16_t qtype; u_int16_t qclass; + char *macro_lookupname; char *lookupname; char * server_name; char *out_filename ; @@ -506,7 +507,7 @@ void printErrorQuick (struct query_state *qry); static void local_exit(void *state); static void *tdig_init(int argc, char *argv[], void (*done)(void *state)); static void process_reply(void * arg, int nrecv, struct timespec now); -static void mk_dns_buff(struct query_state *qry, u_char *packet, +static int mk_dns_buff(struct query_state *qry, u_char *packet, size_t packetlen) ; int ip_addr_cmp (u_int16_t af_a, void *a, u_int16_t af_b, void *b); static void udp_dns_cb(int err, struct evutil_addrinfo *ev_res, void *arg); @@ -514,7 +515,7 @@ static void noreply_callback(int unused UNUSED_PARAM, const short event UNUSED_ static void free_qry_inst(struct query_state *qry); static void ready_callback (int unused, const short event, void * arg); -u_int32_t get32b (char *p); +u_int32_t get32b (unsigned char *p); void ldns_write_uint16(void *dst, uint16_t data); uint16_t ldns_read_uint16(const void *src); unsigned char* ReadName(unsigned char *base, size_t size, size_t offset, @@ -673,7 +674,7 @@ int ip_addr_cmp (u_int16_t af_a, void *a, u_int16_t af_b, void *b) return 1; } -static void mk_dns_buff(struct query_state *qry, u_char *packet, +static int mk_dns_buff(struct query_state *qry, u_char *packet, size_t packetlen) { struct DNS_HEADER *dns = NULL; @@ -756,7 +757,7 @@ static void mk_dns_buff(struct query_state *qry, u_char *packet, qry->lookupname); // fill the query portion. } if (qnamelen == -1) - return; /* Do we need to tell anybody? */ + return -1; qinfo =(struct QUESTION*)&packet[sizeof(struct DNS_HEADER) + qnamelen]; @@ -823,9 +824,9 @@ static void mk_dns_buff(struct query_state *qry, u_char *packet, crondlog(LVL5 "payload : %s", pbuf.buf); buf_cleanup(&pbuf); } -} - + return 0; +} /* Attempt to transmit a UDP DNS Request to a server. TCP is else where */ static void tdig_send_query_callback(int unused UNUSED_PARAM, const short event UNUSED_PARAM, void *h) @@ -848,7 +849,19 @@ static void tdig_send_query_callback(int unused UNUSED_PARAM, const short event //AA delete qry->outbuff = outbuff; qry->xmit_time= time(NULL); clock_gettime(CLOCK_MONOTONIC_RAW, &qry->xmit_time_ts); - mk_dns_buff(qry, outbuff, MAX_DNS_OUT_BUF_SIZE); + r= mk_dns_buff(qry, outbuff, MAX_DNS_OUT_BUF_SIZE); + if (r == -1) + { + /* Can't construct a DNS query */ + free (outbuff); + outbuff = NULL; + snprintf(line, DEFAULT_LINE_LENGTH, + "%s \"err\" : \"unable to format DNS query\"", + qry->err.size ? ", " : ""); + buf_add(&qry->err, line, strlen(line)); + printReply (qry, 0, NULL); + return; + } do { if (qry->udp_fd != -1) { @@ -1215,6 +1228,7 @@ static void tcp_readcb(struct bufferevent *bev UNUSED_PARAM, void *ptr) if (qry->response_out) fwrite(line, n, 1, qry->resp_file); buf_add(&qry->packet, line, n); + crondlog(LVL5 "in readcb %s %s got %d bytes, need %d", qry->str_Atlas, qry->server_name, qry->packet.size, qry->wire_size); if(qry->wire_size == qry->packet.size) { crondlog(LVL5 "in readcb %s %s red %d bytes ", qry->str_Atlas, qry->server_name, qry->wire_size); crondlog(LVL5 "qry pointer address readcb %p qry.id, %d", qry->qryid); @@ -1393,14 +1407,15 @@ static bool argProcess (int argc, char *argv[], struct query_state *qry ) else qry->server_name = strdup(argv[optind]); - if (qry->lookupname == NULL) { + if (qry->macro_lookupname == NULL) { crondlog(LVL9 "ERROR no query in command line"); tdig_delete(qry); return TRUE; } - if (qry->lookupname[strlen(qry->lookupname) - 1] != '.') { - crondlog(LVL9 "ERROR query %s does not end with a dot ", qry->lookupname); + if (qry->macro_lookupname[strlen(qry->macro_lookupname) - 1] != '.') { + crondlog(LVL9 "ERROR query %s does not end with a dot ", + qry->macro_lookupname); tdig_delete(qry); return TRUE; } @@ -1494,6 +1509,7 @@ static void *tdig_init(int argc, char *argv[], void (*done)(void *state)) buf_init(&qry->err, -1); buf_init(&qry->packet, -1); qry->opt_resolv_conf = 0; + qry->macro_lookupname = NULL; qry->lookupname = NULL; qry->dst_ai_family = 0; qry->loc_ai_family = 0; @@ -1559,7 +1575,8 @@ static void *tdig_init(int argc, char *argv[], void (*done)(void *state)) qry->infname= strdup(optarg); break; case 'b': - qry->lookupname = strdup ("version.bind."); + qry->macro_lookupname = + strdup ("version.bind."); break; case 'd': @@ -1571,11 +1588,12 @@ static void *tdig_init(int argc, char *argv[], void (*done)(void *state)) break; case 'h': - qry->lookupname = strdup("hostname.bind."); + qry->macro_lookupname = + strdup("hostname.bind."); break; case 'i': - qry->lookupname = strdup("id.server."); + qry->macro_lookupname = strdup("id.server."); break; case 'n': @@ -1587,7 +1605,8 @@ static void *tdig_init(int argc, char *argv[], void (*done)(void *state)) break; case 'r': - qry->lookupname = strdup("version.server."); + qry->macro_lookupname = + strdup("version.server."); break; case 'R': @@ -1597,7 +1616,7 @@ static void *tdig_init(int argc, char *argv[], void (*done)(void *state)) case 's': qry->qtype = T_SOA; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case 't': @@ -1660,7 +1679,7 @@ static void *tdig_init(int argc, char *argv[], void (*done)(void *state)) case O_QUERY: qry->opt_query_arg = 1; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case O_RESOLV_CONF : @@ -1681,163 +1700,163 @@ static void *tdig_init(int argc, char *argv[], void (*done)(void *state)) case (100000 + T_A): qry->qtype = T_A; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_AAAA ): qry->qtype = T_AAAA ; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_AFSDB ): qry->qtype = T_AFSDB ; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_ANY): qry->qtype = T_ANY ; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_APL): qry->qtype = T_APL ; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_AXFR ): qry->qtype = T_AXFR ; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_CAA): qry->qtype = T_CAA ; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_CERT): qry->qtype = T_CERT ; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_CNAME): qry->qtype = T_CNAME; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_DLV): qry->qtype = T_DLV; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_DNAME): qry->qtype = T_DNAME; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_DNSKEY): qry->qtype = T_DNSKEY; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_DS): qry->qtype = T_DS; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_IPSECKEY): qry->qtype = T_IPSECKEY; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_LOC): qry->qtype = T_LOC; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_MX): qry->qtype = T_MX; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_NAPTR): qry->qtype = T_NAPTR; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_NS): qry->qtype = T_NS; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_NSEC): qry->qtype = T_NSEC; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_NSEC3): qry->qtype = T_NSEC3; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_NSEC3PARAM): qry->qtype = T_NSEC3PARAM; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_PTR): qry->qtype = T_PTR; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_RRSIG): qry->qtype = T_RRSIG; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_RP): qry->qtype = T_RP; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_SIG): qry->qtype = T_SIG; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_SPF): qry->qtype = T_SPF; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_SRV): qry->qtype = T_SRV; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_SSHFP): @@ -1849,25 +1868,25 @@ static void *tdig_init(int argc, char *argv[], void (*done)(void *state)) case (100000 + T_TA): qry->qtype = T_TA; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_TLSA): qry->qtype = T_TLSA; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_TSIG): qry->qtype = T_TSIG; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case (100000 + T_TXT): qry->qtype = T_TXT; qry->qclass = C_IN; - qry->lookupname = strdup(optarg); + qry->macro_lookupname = strdup(optarg); break; case 200000 + 'W': @@ -2003,6 +2022,23 @@ void tdig_start (void *arg) switch(qry->qst) { case STATUS_FREE : + /* Macro processing */ + if (qry->lookupname) + { + free(qry->lookupname); + qry->lookupname= NULL; + } + qry->lookupname= + atlas_name_macro(qry->macro_lookupname); + if (qry->lookupname == NULL) + { + snprintf(line, DEFAULT_LINE_LENGTH, + "\"err\": \"macro expansion failed\""); + buf_add(&qry->err, line, strlen(line)); + printReply (qry, 0, NULL); + return; + } + /* Get time in case we don't send any packet */ qry->xmit_time= time(NULL); qry->resolv_i = 0; @@ -2393,6 +2429,11 @@ static int tdig_delete(void *state) free(qry->out_filename); qry->out_filename = NULL ; } + if(qry->macro_lookupname) + { + free(qry->macro_lookupname); + qry->macro_lookupname = NULL; + } if(qry->lookupname) { free(qry->lookupname); @@ -2619,10 +2660,10 @@ void printReply(struct query_state *qry, int wire_size, unsigned char *result) snprintf(line, DEFAULT_LINE_LENGTH, ",\"result\" : { \"rt\" : %.3f,", qry->triptime); buf_add(&qry->result,line, strlen(line)); - JD (size, wire_size); + JD_NC (size, wire_size); if(qry->opt_abuf) { - snprintf(line, DEFAULT_LINE_LENGTH, "\"abuf\" : \""); + snprintf(line, DEFAULT_LINE_LENGTH, ", \"abuf\" : \""); buf_add(&qry->result,line, strlen(line)); buf_add_b64(&qry->result, result, wire_size, 0); AS("\""); @@ -2982,7 +3023,7 @@ int dns_namelen(unsigned char *base, size_t offset, size_t size) * eg. used to extract serial number from soa packet */ u_int32_t -get32b (char *p) +get32b (unsigned char *p) { u_int32_t var; diff --git a/eperd/ping.c b/eperd/ping.c index a479312..53f2967 100644 --- a/eperd/ping.c +++ b/eperd/ping.c @@ -26,13 +26,14 @@ #define DBQ(str) "\"" #str "\"" -#define PING_OPT_STRING ("!46rc:s:A:B:O:i:I:R:W:") +#define PING_OPT_STRING ("!46prc:s:A:B:O:i:I:R:W:") enum { opt_4 = (1 << 0), opt_6 = (1 << 1), - opt_r = (1 << 2), + opt_p = (1 << 2), + opt_r = (1 << 3), }; /* Intervals and timeouts (all are in milliseconds unless otherwise specified) @@ -99,6 +100,7 @@ struct pingstate char *interface; int pingcount; char *out_filename; + char include_probe_id; char delay_name_res; unsigned interval; @@ -479,13 +481,15 @@ static int mkcksum(u_short *p, int n) * ho hosts being monitored */ static void fmticmp4(u_char *buffer, size_t *sizep, u_int8_t seq, - uint32_t idx, pid_t pid, struct cookie *cookiep) + uint32_t idx, pid_t pid, struct cookie *cookiep, + int include_probe_id) { - size_t minlen; + int probe_id; + size_t minlen, len; struct icmp *icmp = (struct icmp *) buffer; struct evdata *data = (struct evdata *) (buffer + ICMP_MINLEN); - struct timespec now; + char probe_id_line[80]; minlen= sizeof(*data); if (*sizep < minlen) @@ -509,6 +513,30 @@ static void fmticmp4(u_char *buffer, size_t *sizep, u_int8_t seq, data->index = idx; /* index into an array */ data->cookie= *cookiep; + if (include_probe_id) + { + probe_id= get_probe_id(); + if (probe_id == -1) + { + snprintf(probe_id_line, sizeof(probe_id_line), + "RIPE Atlas probe "); + } + else + { + snprintf(probe_id_line, sizeof(probe_id_line), + "RIPE Atlas probe %d", probe_id); + } + + len= strlen(probe_id_line); + if (*sizep < sizeof(*data) + len) + len= *sizep - sizeof(*data); + if (len) + { + memcpy(buffer + ICMP_MINLEN + sizeof(*data), + probe_id_line, len); + } + } + /* Last, compute ICMP checksum */ icmp->icmp_cksum = 0; icmp->icmp_cksum = mkcksum((u_short *) icmp, ICMP_MINLEN + *sizep); /* ones complement checksum of struct */ @@ -531,13 +559,15 @@ static void fmticmp4(u_char *buffer, size_t *sizep, u_int8_t seq, * ho hosts being monitored */ static void fmticmp6(u_char *buffer, size_t *sizep, - u_int8_t seq, uint32_t idx, pid_t pid, struct cookie *cookiep) + u_int8_t seq, uint32_t idx, pid_t pid, struct cookie *cookiep, + int include_probe_id) { - size_t minlen; + int probe_id; + size_t minlen, len; struct icmp6_hdr *icmp = (struct icmp6_hdr *) buffer; struct evdata *data = (struct evdata *) (buffer + ICMP6_HDRSIZE); - struct timespec now; + char probe_id_line[80]; minlen= sizeof(*data); if (*sizep < minlen) @@ -559,6 +589,31 @@ static void fmticmp6(u_char *buffer, size_t *sizep, data->index = idx; /* index into an array */ data->cookie= *cookiep; + if (include_probe_id) + { + probe_id= get_probe_id(); + if (probe_id == -1) + { + snprintf(probe_id_line, sizeof(probe_id_line), + "RIPE Atlas probe "); + } + else + { + snprintf(probe_id_line, sizeof(probe_id_line), + "RIPE Atlas probe %d", probe_id); + } + + len= strlen(probe_id_line); + if (*sizep < sizeof(*data) + len) + len= *sizep - sizeof(*data); + if (len) + { + memcpy(buffer + ICMP6_HDRSIZE + sizeof(*data), + probe_id_line, len); + } + } + + icmp->icmp6_cksum = 0; } @@ -594,7 +649,7 @@ static void ping_xmit(struct pingstate *host) { /* Format the ICMP Echo Reply packet to send */ fmticmp6(base->packet, &host->cursize, host->seq, host->index, - base->pid, &host->cookie); + base->pid, &host->cookie, host->include_probe_id); host->loc_socklen= sizeof(host->loc_sin6); getsockname(host->socket, &host->loc_sin6, &host->loc_socklen); @@ -616,8 +671,9 @@ static void ping_xmit(struct pingstate *host) else { /* Format the ICMP Echo Reply packet to send */ - fmticmp4(base->packet, &host->cursize, host->seq, host->index, - base->pid, &host->cookie); + fmticmp4(base->packet, &host->cursize, host->seq, + host->index, base->pid, &host->cookie, + host->include_probe_id); host->loc_socklen= sizeof(host->loc_sin6); getsockname(host->socket, &host->loc_sin6, &host->loc_socklen); @@ -1107,7 +1163,7 @@ static void *ping_init(int __attribute((unused)) argc, char *argv[], { static struct pingbase *ping_base; - int i, r, fd, newsiz, delay_name_res; + int i, r, fd, newsiz, include_probe_id, delay_name_res; uint32_t opt; unsigned pingcount; /* must be int-sized */ unsigned size, interval; @@ -1241,6 +1297,7 @@ static void *ping_init(int __attribute((unused)) argc, char *argv[], af= AF_INET; else af= AF_INET6; + include_probe_id= !!(opt & opt_p); delay_name_res= !!(opt & opt_r); delay_name_res= 1; /* Always enabled, leave the old code in * place for now. @@ -1279,6 +1336,7 @@ static void *ping_init(int __attribute((unused)) argc, char *argv[], state->base = ping_base; state->af= af; + state->include_probe_id= include_probe_id; state->delay_name_res= delay_name_res; state->interval= interval; state->interface= interface ? strdup(interface) : NULL; diff --git a/eperd/sslgetcert.c b/eperd/sslgetcert.c index cba0f42..dceabfd 100644 --- a/eperd/sslgetcert.c +++ b/eperd/sslgetcert.c @@ -89,6 +89,7 @@ struct state char connecting; char *hostname; char *portname; + char *sni; struct bufferevent *bev; enum readstate readstate; enum writestate writestate; @@ -488,6 +489,17 @@ static void hsbuf_add(struct hsbuf *hsbuf, const void *buf, size_t len) buf_add(&hsbuf->buffer, buf, len); } +static void hsbuf_add_u16(struct hsbuf *hsbuf, unsigned u16) +{ + uint8_t c; + + c= (u16 >> 8); + buf_add(&hsbuf->buffer, &c, 1); + + c= u16; + buf_add(&hsbuf->buffer, &c, 1); +} + static void hsbuf_cleanup(struct hsbuf *hsbuf) { buf_cleanup(&hsbuf->buffer); @@ -549,7 +561,6 @@ static void add_sessionid(struct hsbuf *hsbuf) static void add_ciphers(struct hsbuf *hsbuf) { - uint8_t c; size_t len; uint8_t ciphers[]= { 0xc0,0x0a, /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA */ @@ -565,11 +576,7 @@ static void add_ciphers(struct hsbuf *hsbuf) len= sizeof(ciphers); - c= len >> 8; - hsbuf_add(hsbuf, &c, 1); - c= len; - hsbuf_add(hsbuf, &c, 1); - + hsbuf_add_u16(hsbuf, len); hsbuf_add(hsbuf, ciphers, len); } @@ -587,6 +594,41 @@ static void add_compression(struct hsbuf *hsbuf) hsbuf_add(hsbuf, compression, len); } +static void add_sni(struct hsbuf *hsbuf, const char *server_name) +{ + /* Assume there is only a single extension with one hostname. + * Add the following: + * + * size of extensions vector, 16-bit + * extension_type (server_name, 0), 16-bit + * size of extension_data vector, 16-bit + * size of server_name_list, 16-bit + * name_type (host_name, 0), 8-bit + * size of HostName, 16-bit + * actual hostname. + */ + + uint8_t c; + size_t size_hostname, size_server_name_list, size_extension_data, + size_extensions; + + size_hostname= strlen(server_name); + size_server_name_list= 1 /*name_type*/ + 2 /*size_hostname*/ + + size_hostname; + size_extension_data= 2 /*size_server_name_list*/ + + size_server_name_list; + size_extensions= 2 /*extension_type*/ + 2 /*size_extension_data*/ + + size_extension_data; + + hsbuf_add_u16(hsbuf, size_extensions); + hsbuf_add_u16(hsbuf, 0 /* server_name */); + hsbuf_add_u16(hsbuf, size_extension_data); + hsbuf_add_u16(hsbuf, size_server_name_list); + c= 0; /* host_name */ + hsbuf_add(hsbuf, &c, 1); + hsbuf_add_u16(hsbuf, size_hostname); + hsbuf_add(hsbuf, server_name, size_hostname); +} static struct hgbase *sslgetcert_base_new(struct event_base *event_base) { @@ -606,6 +648,9 @@ static void timeout_callback(int __attribute((unused)) unused, const short __attribute((unused)) event, void *s) { struct state *state; + double resptime; + char hostbuf[NI_MAXHOST]; + char line[80]; state= ENV2STATE(s); @@ -618,6 +663,18 @@ static void timeout_callback(int __attribute((unused)) unused, tu_restart_connect(&state->tu_env); return; } + + getnameinfo((struct sockaddr *)&state->loc_sin6, + state->loc_socklen, hostbuf, sizeof(hostbuf), NULL, 0, + NI_NUMERICHOST); + snprintf(line, sizeof(line), DBQ(src_addr) ":" DBQ(%s) ", " , hostbuf); + add_str(state, line); + + resptime= (state->t_connect.tv_sec- state->start.tv_sec)*1e3 + + (state->t_connect.tv_nsec-state->start.tv_nsec)/1e6; + snprintf(line, sizeof(line), DBQ(ttc) ": %f, ", resptime); + add_str(state, line); + switch(state->readstate) { case READ_HELLO: @@ -640,7 +697,7 @@ static void *sslgetcert_init(int __attribute((unused)) argc, char *argv[], int c, i, only_v4, only_v6, major, minor; size_t newsiz; char *hostname, *str_port, *infname, *version_str; - char *output_file, *A_arg, *B_arg; + char *output_file, *A_arg, *B_arg, *h_arg; char *response_in, *response_out; struct state *state; FILE *fh; @@ -650,6 +707,7 @@ static void *sslgetcert_init(int __attribute((unused)) argc, char *argv[], version_str= NULL; A_arg= NULL; B_arg= NULL; + h_arg= NULL; infname= NULL; str_port= NULL; response_in= NULL; @@ -667,7 +725,8 @@ static void *sslgetcert_init(int __attribute((unused)) argc, char *argv[], /* Allow us to be called directly by another program in busybox */ optind= 0; - while (c= getopt_long(argc, argv, "A:B:O:R:V:W:i:p:46", longopts, NULL), c != -1) + while (c= getopt_long(argc, argv, "A:B:h:O:R:V:W:i:p:46", + longopts, NULL), c != -1) { switch(c) { @@ -677,6 +736,9 @@ static void *sslgetcert_init(int __attribute((unused)) argc, char *argv[], case 'B': B_arg= optarg; break; + case 'h': + h_arg= optarg; + break; case 'O': output_file= optarg; break; @@ -802,6 +864,7 @@ static void *sslgetcert_init(int __attribute((unused)) argc, char *argv[], state->response_out= response_out ? strdup(response_out) : NULL; state->infname= infname ? strdup(infname) : NULL; state->hostname= strdup(hostname); + state->sni= h_arg ? strdup(h_arg) : NULL; state->major_version= major; state->minor_version= minor; if (str_port) @@ -1411,6 +1474,9 @@ static void writecb(struct bufferevent *bev, void *ptr) add_ciphers(&hsbuf); add_compression(&hsbuf); + if (state->sni) + add_sni(&hsbuf, state->sni); + hsbuf_final(&hsbuf, HS_CLIENT_HELLO, &msgoutbuf); msgbuf_final(&msgoutbuf, MSG_HANDSHAKE); diff --git a/include/libbb.h b/include/libbb.h index 96c9bab..add297c 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -320,6 +320,7 @@ extern int get_timesync(void); extern int get_atlas_fw_version(void); extern int bind_interface(int socket, int af, char *name); extern int atlas_check_addr(const struct sockaddr *sa, socklen_t len); +extern char *atlas_name_macro(char *str); int ndelay_on(int fd) FAST_FUNC; int ndelay_off(int fd) FAST_FUNC; diff --git a/libbb/Kbuild b/libbb/Kbuild index 9a17725..280d40d 100644 --- a/libbb/Kbuild +++ b/libbb/Kbuild @@ -12,6 +12,7 @@ lib-y += atlas_bb64.o lib-y += atlas_probe.o lib-y += atlas_timesync.o lib-y += atlas_check_addr.o +lib-y += atlas_name_macro.o lib-y += bb_askpass.o lib-y += bb_basename.o lib-y += bb_do_delay.o diff --git a/libbb/atlas_name_macro.c b/libbb/atlas_name_macro.c new file mode 100644 index 0000000..0674fd0 --- /dev/null +++ b/libbb/atlas_name_macro.c @@ -0,0 +1,87 @@ +#include "libbb.h" + +#define URANDOM_DEV "/dev/urandom" + +static char hex_chars[]= "0123456789abcdef"; + +char *atlas_name_macro(char *str) +{ + unsigned char c; + int i, fd; + size_t len; + char *p, *in, *out; + char buf[256]; + unsigned char random_buf[8]; + + p= strchr(str, '$'); + if (p == NULL) + return strdup(str); + + in= str; + out= buf; + + while (*in) + { + p= strchr(in, '$'); + if (p == NULL) + { + strlcpy(out, in, buf+sizeof(buf)-out); + break; + } + if (p != in) + { + len= p-in; + + if (len+1 > buf+sizeof(buf)-out) + return NULL; + memcpy(out, in, len); + out[len]= '\0'; + + out += len; + } + + switch(p[1]) + { + case 'p': + snprintf(out, buf+sizeof(buf)-out, "%d", + get_probe_id()); + break; + case 't': + snprintf(out, buf+sizeof(buf)-out, "%ld", + (long)time(NULL)); + break; + case 'r': + /* We need to hex digits per byte in random_buf */ + if (sizeof(random_buf)*2+1 > buf+sizeof(buf)-out) + return NULL; + + fd= open(URANDOM_DEV, O_RDONLY); + + /* Best effort, just ignore errors */ + if (fd != -1) + { + read(fd, random_buf, sizeof(random_buf)); + close(fd); + } + + for (i= 0; i> 4) & 0xf]; + out[1]= hex_chars[c & 0xf]; + out += 2; + } + + out[0]= '\0'; + break; + + default: + return NULL; + } + in= p+2; + out += strlen(out); + } + + return strdup(buf); +} diff --git a/libbb/atlas_probe.c b/libbb/atlas_probe.c index a3264fb..8a5c8f0 100644 --- a/libbb/atlas_probe.c +++ b/libbb/atlas_probe.c @@ -6,13 +6,17 @@ #include "libbb.h" int get_probe_id(void) { - int probe_id; + static int probe_id= -1; + size_t len; char *check; const char *key; FILE *fp; char buf[80]; + if (probe_id > 0) + return probe_id; /* Assume probe ID never changes */ + fp= fopen("/home/atlas/status/reg_init_reply.txt", "r"); if (!fp) return -1; diff --git a/shell/hush.c b/shell/hush.c index d696d73..5ef39bc 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -73,6 +73,7 @@ #if ENABLE_HUSH_CASE #include #endif +#include #define HUSH_VER_STR "0.91" @@ -774,6 +775,7 @@ static int builtin_rxtxrpt(char **argv); static int builtin_rptaddrs(char **argv); static int builtin_rptuptime(char **argv); static int builtin_onlyuptime(char **argv); +static int builtin_reboot_probe(char **argv); static int builtin_true(char **argv); static int builtin_set(char **argv); static int builtin_shift(char **argv); @@ -836,6 +838,7 @@ static const struct built_in_command bltins[] = { BLTIN("rptaddrs" , builtin_rptaddrs, "report address(es), route(s), and dns"), BLTIN("rptuptime" , builtin_rptuptime, "report uptime"), BLTIN("onlyuptime" , builtin_onlyuptime, "report uptime in seconds"), + BLTIN("reboot_probe" , builtin_reboot_probe, "built-in reboot command"), BLTIN("echo" , builtin_echo, "Write to stdout"), BLTIN("eval" , builtin_eval, "Construct and run shell command"), BLTIN("exec" , builtin_exec, "Execute command, don't return to shell"), @@ -4797,6 +4800,15 @@ static int builtin_onlyuptime(char **argv __attribute((unused))) return 0; } +static int builtin_reboot_probe(char **argv __attribute((unused))) +{ + int r; + + sync(); + r= reboot(RB_AUTOBOOT); + return r; +} + static int builtin_rchoose(char **argv) { int argc = 0; -- cgit v1.2.3