aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--eperd/evtdig.c141
-rw-r--r--eperd/ping.c82
-rw-r--r--eperd/sslgetcert.c82
-rw-r--r--include/libbb.h1
-rw-r--r--libbb/Kbuild1
-rw-r--r--libbb/atlas_name_macro.c87
-rw-r--r--libbb/atlas_probe.c6
-rw-r--r--shell/hush.c12
8 files changed, 341 insertions, 71 deletions
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 <unknown>");
+ }
+ 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 <unknown>");
+ }
+ 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<sizeof(random_buf); i++)
+ {
+ c= random_buf[i];
+
+ out[0]= hex_chars[(c >> 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 <fnmatch.h>
#endif
+#include <sys/reboot.h>
#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;