/*------------------------------------------------------------------------ * int ttp_authenticate(ttp_session_t *session, u_char *secret); * * Given an active Tsunami session, returns 0 if we are able to * negotiate authentication successfully and a non-zero value * otherwise. * * The negotiation process works like this: * * (1) The server sends 512 bits of random data to the client * [this process]. * * (2) The client XORs 512 bits of the shared secret onto this * random data and responds with the MD5 hash of the result. * * (3) The server does the same thing and compares the result. * If the authentication succeeds, the server transmits a * result byte of 0. Otherwise, it transmits a non-zero * result byte. *------------------------------------------------------------------------*/ int ttp_authenticate(ttp_session_t *session, u_char *secret) { u_char random[64]; /* the buffer of random data */ u_char digest[16]; /* the MD5 message digest (for the server) */ u_char result; /* the result byte from the server */ int status; /* return status from function calls */ /* read in the shared secret and the challenge */ status = fread(random, 1, 64, session->server); if (status < 64) return warn("Could not read authentication challenge from server"); /* prepare the proof of the shared secret and destroy the password */ prepare_proof(random, 64, secret, digest); while (*secret) *(secret++) = '\0'; /* send the response to the server */ status = fwrite(digest, 1, 16, session->server); if ((status < 16) || fflush(session->server)) return warn("Could not send authentication response"); /* read the results back from the server */ status = fread(&result, 1, 1, session->server); if (status < 1) return warn("Could not read authentication status"); /* check the result byte */ return (result == 0) ? 0 : -1; }
/*------------------------------------------------------------------------ * int ttp_authenticate(ttp_session_t *session, const u_char *secret); * * Given an active Tsunami session, returns 0 if we are able to * negotiate authentication successfully and a non-zero value * otherwise. * * The negotiation process works like this: * * (1) The server [this process] sends 512 bits of random data * to the client. * * (2) The client XORs 512 bits of the shared secret onto this * random data and responds with the MD5 hash of the result. * * (3) The server does the same thing and compares the result. * If the authentication succeeds, the server transmits a * result byte of 0. Otherwise, it transmits a non-zero * result byte. *------------------------------------------------------------------------*/ int ttp_authenticate(ttp_session_t *session, const u_char *secret) { u_char random[64]; /* the buffer of random data */ u_char server_digest[16]; /* the MD5 message digest (for us) */ u_char client_digest[16]; /* the MD5 message digest (for the client) */ int i; int status; /* obtain the random data */ status = get_random_data(random, 64); if (status < 0) return warn("Access to random data is broken"); /* send the random data to the client */ status = full_write(session->client_fd, random, 64); if (status < 0) return warn("Could not send authentication challenge to client"); /* read the results back from the client */ status = full_read(session->client_fd, client_digest, 16); if (status < 0) return warn("Could not read authentication response from client"); /* compare the two digests */ prepare_proof(random, 64, secret, server_digest); for (i = 0; i < 16; ++i) if (client_digest[i] != server_digest[i]) { full_write(session->client_fd, "\001", 1); return warn("Authentication failed"); } /* try to tell the client it worked */ status = full_write(session->client_fd, "\000", 1); if (status < 0) return warn("Could not send authentication confirmation to client"); /* we succeeded */ return 0; }