- if (now.tv_usec > start.tv_usec) {
- now.tv_usec -= 1000000;
- now.tv_sec += 1;
- }
- tv.tv_sec = start.tv_sec + tbl[ind] - now.tv_sec;
- tv.tv_usec = start.tv_usec - now.tv_usec;
-
- /* --- Sort out file descriptors to watch --- */
-
- FD_ZERO(&fds);
- FD_SET(fd, &fds);
-
- /* --- Wait for them --- */
-
- i = select(FD_SETSIZE, &fds, 0, 0, &tv);
- if (i == 0 || (i < 0 && errno == EINTR))
- continue;
- if (i < 0)
- die("error waiting for reply: %s", strerror(errno));
-
- /* --- A reply should be waiting now --- */
-
- {
- struct sockaddr_in sin;
- int slen = sizeof(sin);
- unsigned char buff[256];
- int answer;
-
- /* --- Read the reply data --- */
-
- if (recvfrom(fd, (char *)buff, sizeof(buff), 0,
- (struct sockaddr *)&sin, &slen) < 0)
- die("error reading server's reply: %s", strerror(errno));
-
- IF_TRACING(TRACE_CLIENT, {
- struct hostent *h = gethostbyaddr((char *)&sin.sin_addr,
- sizeof(sin.sin_addr), AF_INET);
- trace(TRACE_CLIENT, "client: reply received from %s port %i",
- h ? h->h_name : inet_ntoa(sin.sin_addr),
- ntohs(sin.sin_port));
- })
-
- /* --- Verify the sender --- *
- *
- * This is more to avoid confusion than for security: an active
- * attacker is quite capable of forging the source address. We rely
- * on the checksum in the reply packet for authentication.
- */
-
- for (i = 0; i < n_serv; i++) {
- if (sin.sin_addr.s_addr == serv[i].sin_addr.s_addr &&
- sin.sin_port == serv[i].sin_port)
- break;
- }
- if (i >= n_serv) {
- T( trace(TRACE_CLIENT, "client: reply from unknown host"); )
- continue;
- }
-
- /* --- Unpack and verify the response --- */
-
- answer = crypt_unpackReply(buff, sk, t, pid);
- if (answer < 0) {
- T( trace(TRACE_CLIENT,
- "client: invalid or corrupt reply packet"); )
- continue;
- }
+ IF_TRACING(TRACE_CLIENT, {
+ struct hostent *h = gethostbyaddr((char *)&sin.sin_addr,
+ sizeof(sin.sin_addr), AF_INET);
+ trace(TRACE_CLIENT, "client: reply received from %s port %i",
+ h ? h->h_name : inet_ntoa(sin.sin_addr),
+ ntohs(sin.sin_port));
+ })
+
+ /* --- Verify the sender --- *
+ *
+ * This is more to avoid confusion than for security: an active
+ * attacker is quite capable of forging the source address. We rely
+ * on the signature in the reply packet for authentication.
+ */
+
+ for (i = 0; i < n_serv; i++) {
+ if (sin.sin_addr.s_addr == serv[i].sin_addr.s_addr &&
+ sin.sin_port == serv[i].sin_port)
+ break;
+ }
+ if (i >= n_serv) {
+ T( trace(TRACE_CLIENT, "client: reply from unknown host"); )
+ continue;
+ }
+
+ /* --- Unpack and verify the response --- */
+
+ buf_init(&b, rbuff, sz);
+ if (buf_ensure(&b, sizeof(hmsg))) goto bad;
+ if (memcmp(BCUR(&b), hmsg, sizeof(hmsg)) != 0) goto bad;
+ BSTEP(&b, sizeof(hmsg));
+ if ((ans = buf_getbyte(&b)) < 0) goto bad;
+
+ sha_init(&hc);
+ sha_hash(&hc, BBASE(&b), BLEN(&b));
+ sha_done(&hc, h);
+ if ((r = buf_getmp(&b)) == 0 || (s = buf_getmp(&b)) == 0) goto bad;
+ m = mp_loadb(MP_NEW, h, sizeof(h));
+
+ key_mkiter(&ki, &f);
+ while ((k = key_next(&ki)) != 0) {
+ if (key_expired(k)) continue;
+ if (strcmp(k->type, "become-dsa") != 0) continue;
+ if (key_fetch(kp, k)) continue;
+ i = dsa_vrfy(&kpub.dp, kpub.y, m, r, s);
+ dsa_pubfree(&kpub);
+ if (i) {
+ key_fetchdone(kp);
+ key_close(&f);