123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- From 64ee5ba5cad6298f72271539cb96e2de164dfc2f Mon Sep 17 00:00:00 2001
- From: Mats Erik Andersson <gnu@gisladisker.se>
- Date: Tue, 16 Feb 2016 23:29:25 +0100
- Subject: [PATCH 18/60] traceroute: Subprivileged use case.
- A fallback for ICMP tracing relevant to GNU/Linux is implemented,
- allowing a rudimentary but suid-less use case.
- ---
- ChangeLog | 18 ++++++++++++++++++
- src/traceroute.c | 30 +++++++++++++++++++++++++++++-
- 2 files changed, 47 insertions(+), 1 deletion(-)
- diff --git a/ChangeLog b/ChangeLog
- index e79308bc..f01a330c 100644
- --- a/ChangeLog
- +++ b/ChangeLog
- @@ -1,3 +1,21 @@
- +2016-02-16 Mats Erik Andersson <gnu@gisladisker.se>
- +
- + traceroute: Subprivileged use case.
- + A fallback for ICMP tracing relevant to GNU/Linux is implemented,
- + allowing a rudimentary but suid-less use case. The ability to
- + identify intermediary hosts is missing, due to the crippled
- + capability of receiving ICMP packets other than ICMP_ECHOREPLY.
- +
- + * src/traceroute.c (struct trace): New member `no_ident'.
- + (trace_init): Initiate `t->no_ident'.
- + <type TRACE_ICMP or TRACE_UDP>: In case a raw socket for an ICMP
- + protocol fails, fall back to a datagram socket.
- + (trace_read) <type TRACE_ICMP>: Short circuit `ic->icmp_id != pid'
- + with the conditional `t->no_ident == 0'.
- + (trace_write) <type TRACE_ICMP>: New variable I. Initialize HDR
- + to its full extent. If `t->no_ident' is non-zero, insert our
- + intended target as payload of HDR for trace identification.
- +
- 2016-02-12 Mats Erik Andersson <gnu@gisladisker.se>
-
- ping: Implement subprivileged echo method.
- diff --git a/src/traceroute.c b/src/traceroute.c
- index 785dc6f2..2a56a53d 100644
- --- a/src/traceroute.c
- +++ b/src/traceroute.c
- @@ -75,6 +75,7 @@ typedef struct trace
- {
- int icmpfd, udpfd;
- enum trace_type type;
- + int no_ident;
- struct sockaddr_in to, from;
- int ttl;
- struct timeval tsent;
- @@ -476,6 +477,7 @@ trace_init (trace_t * t, const struct sockaddr_in to,
- t->type = type;
- t->to = to;
- t->ttl = opt_ttl;
- + t->no_ident = 0;
-
- if (t->type == TRACE_UDP)
- {
- @@ -494,6 +496,21 @@ trace_init (trace_t * t, const struct sockaddr_in to,
- if (protocol)
- {
- t->icmpfd = socket (PF_INET, SOCK_RAW, protocol->p_proto);
- + if (t->icmpfd < 0 && (errno == EPERM || errno == EACCES))
- + {
- + /* A subprivileged user on GNU/Linux might be allowed
- + * to create ICMP packets from a datagram socket.
- + * Such packets are always severely crippled.
- + */
- + errno = 0;
- + t->icmpfd = socket (PF_INET, SOCK_DGRAM, protocol->p_proto);
- + t->no_ident++;
- +
- + /* Recover error message for non-Linux systems. */
- + if (errno == EPROTONOSUPPORT)
- + errno = EPERM;
- + }
- +
- if (t->icmpfd < 0)
- error (EXIT_FAILURE, errno, "socket");
-
- @@ -609,7 +626,7 @@ trace_read (trace_t * t, int * type, int * code)
-
- if (ic->icmp_type == ICMP_ECHOREPLY
- && (ntohs (ic->icmp_seq) != seqno
- - || ntohs (ic->icmp_id) != pid))
- + || (ntohs (ic->icmp_id) != pid && t->no_ident == 0)))
- return -1;
-
- if (ic->icmp_type == ICMP_TIME_EXCEEDED
- @@ -685,6 +702,17 @@ trace_write (trace_t * t)
- case TRACE_ICMP:
- {
- icmphdr_t hdr;
- + int i;
- +
- + /* Deposit deterministic values throughout the header! */
- + for (i = 0; i < sizeof (hdr); ++i)
- + *((char *) &hdr + i) = i;
- +
- + /* The subprivileged use case of ICMP sent over datagram
- + * sockets needs extra help with identification of target.
- + */
- + if (t->no_ident)
- + *((int *) &hdr + 12 / sizeof(int)) = dest.sin_addr.s_addr;
-
- /* The sequence number is updated to a valid value! */
- if (icmp_echo_encode ((unsigned char *) &hdr, sizeof (hdr),
- --
- 2.26.0.292.g33ef6b2f38
|