* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The name(s) of the authors of this software must not be used to
+ * 2. The name(s) of the authors of this software must not be used to
* endorse or promote products derived from this software without
* prior written permission.
*
- * 4. Redistributions of any form whatsoever must retain the following
+ * 3. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by Paul Mackerras
* <paulus@samba.org>".
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: chap-new.c,v 1.4 2004/01/17 05:47:55 carlsonj Exp $"
+#define RCSID "$Id: chap-new.c,v 1.8 2005/07/13 10:41:58 paulus Exp $"
#include <stdlib.h>
#include <string.h>
#ifdef CHAPMS
#include "chap_ms.h"
+#define MDTYPE_ALL (MDTYPE_MICROSOFT_V2 | MDTYPE_MICROSOFT | MDTYPE_MD5)
+#else
+#define MDTYPE_ALL (MDTYPE_MD5)
#endif
+int chap_mdtype_all = MDTYPE_ALL;
+
/* Hook for a plugin to validate CHAP challenge */
int (*chap_verify_hook)(char *name, char *ourname, int id,
struct chap_digest_type *digest,
int challenge_xmits;
int challenge_pktlen;
unsigned char challenge[CHAL_MAX_PKTLEN];
+ char message[256];
} server;
/* Values for flags in chap_client_state and chap_server_state */
int (*verifier)(char *, char *, int, struct chap_digest_type *,
unsigned char *, unsigned char *, char *, int);
char rname[MAXNAMELEN+1];
- char message[256];
if ((ss->flags & LOWERUP) == 0)
return;
if (id != ss->challenge[PPP_HDRLEN+1] || len < 2)
return;
- if ((ss->flags & AUTH_DONE) == 0) {
- if ((ss->flags & CHALLENGE_VALID) == 0)
- return;
+ if (ss->flags & CHALLENGE_VALID) {
response = pkt;
GETCHAR(response_len, pkt);
len -= response_len + 1; /* length of name */
if (len < 0)
return;
- ss->flags &= ~CHALLENGE_VALID;
if (ss->flags & TIMEOUT_PENDING) {
ss->flags &= ~TIMEOUT_PENDING;
UNTIMEOUT(chap_timeout, ss);
verifier = chap_verify_response;
ok = (*verifier)(name, ss->name, id, ss->digest,
ss->challenge + PPP_HDRLEN + CHAP_HDRLEN,
- response, message, sizeof(message));
+ response, ss->message, sizeof(ss->message));
if (!ok || !auth_number()) {
ss->flags |= AUTH_FAILED;
warn("Peer %q failed CHAP authentication", name);
}
- }
+ } else if ((ss->flags & AUTH_DONE) == 0)
+ return;
/* send the response */
p = outpacket_buf;
MAKEHEADER(p, PPP_CHAP);
- mlen = strlen(message);
+ mlen = strlen(ss->message);
len = CHAP_HDRLEN + mlen;
p[0] = (ss->flags & AUTH_FAILED)? CHAP_FAILURE: CHAP_SUCCESS;
p[1] = id;
p[2] = len >> 8;
p[3] = len;
if (mlen > 0)
- memcpy(p + CHAP_HDRLEN, message, mlen);
+ memcpy(p + CHAP_HDRLEN, ss->message, mlen);
output(0, outpacket_buf, PPP_HDRLEN + len);
- if ((ss->flags & AUTH_DONE) == 0) {
- ss->flags |= AUTH_DONE;
+ if (ss->flags & CHALLENGE_VALID) {
+ ss->flags &= ~CHALLENGE_VALID;
if (ss->flags & AUTH_FAILED) {
auth_peer_fail(0, PPP_CHAP);
} else {
- auth_peer_success(0, PPP_CHAP, ss->digest->code,
- name, strlen(name));
+ if ((ss->flags & AUTH_DONE) == 0)
+ auth_peer_success(0, PPP_CHAP,
+ ss->digest->code,
+ name, strlen(name));
if (chap_rechallenge_time) {
ss->flags |= TIMEOUT_PENDING;
TIMEOUT(chap_timeout, ss,
chap_rechallenge_time);
}
}
+ ss->flags |= AUTH_DONE;
}
}
auth_withpeer_success(0, PPP_CHAP, cs->digest->code);
else {
cs->flags |= AUTH_FAILED;
+ error("CHAP authentication failed");
auth_withpeer_fail(0, PPP_CHAP);
}
}
}
if ((cs->flags & (AUTH_STARTED|AUTH_DONE)) == AUTH_STARTED) {
cs->flags &= ~AUTH_STARTED;
+ error("CHAP authentication failed due to protocol-reject");
auth_withpeer_fail(0, PPP_CHAP);
}
}