auth.c (1725B)
1 #include <poll.h> 2 #include <stdint.h> 3 #include <stdlib.h> 4 5 #if defined(__linux__) 6 #include <bsd/stdlib.h> 7 #endif 8 9 #include "warp.h" 10 11 int 12 challenge(int netfd) 13 { 14 unsigned char buf[sizeof(uint64_t)]; 15 unsigned long long outlen; 16 struct pollfd pfd[1]; 17 uint64_t n, reply; 18 int ret; 19 20 arc4random_buf(&n, sizeof(buf)); 21 pack64(buf, n); 22 if (netwrite(netfd, buf, sizeof(buf), &outlen) == PKTFAILED) 23 return -1; 24 25 pfd[0].fd = netfd; 26 pfd[0].events = POLLIN; 27 for (;;) { 28 ret = poll(pfd, 1, AUTHTIMEO * 1000); 29 if (ret < 0) { 30 logwarn("poll"); 31 return -1; 32 } else if (ret == 0) { 33 logwarnx("challenge-response timed out"); 34 return -1; 35 } 36 37 if (pfd[0].revents & (POLLIN | POLLHUP)) { 38 ret = netread(netfd, buf, sizeof(buf), &outlen); 39 if (ret == PKTFAILED) 40 return -1; 41 else if (ret == PKTPARTIAL) 42 continue; 43 if (outlen != sizeof(buf)) 44 return -1; 45 reply = unpack64(buf); 46 if (n + 1 == reply) 47 return 0; 48 } 49 } 50 return -1; 51 } 52 53 int 54 response(int netfd) 55 { 56 unsigned char buf[sizeof(uint64_t)]; 57 unsigned long long outlen; 58 struct pollfd pfd[1]; 59 uint64_t reply; 60 int ret; 61 62 pfd[0].fd = netfd; 63 pfd[0].events = POLLIN; 64 for (;;) { 65 ret = poll(pfd, 1, AUTHTIMEO * 1000); 66 if (ret < 0) { 67 logwarn("poll"); 68 return -1; 69 } else if (ret == 0) { 70 logwarnx("challenge-response timed out"); 71 return -1; 72 } 73 74 if (pfd[0].revents & (POLLIN | POLLHUP)) { 75 ret = netread(netfd, buf, sizeof(buf), &outlen); 76 if (ret == PKTFAILED) 77 return -1; 78 else if (ret == PKTPARTIAL) 79 continue; 80 if (outlen != sizeof(buf)) 81 return -1; 82 reply = unpack64(buf); 83 pack64(buf, reply + 1); 84 if (netwrite(netfd, buf, sizeof(buf), &outlen) == PKTFAILED) 85 return -1; 86 break; 87 } 88 } 89 return 0; 90 }