Beispiel #1
0
static int chapms2_check_success(ppp_pcb *pcb, unsigned char *msg, int len, unsigned char *private_) {
	LWIP_UNUSED_ARG(pcb);

	if ((len < MS_AUTH_RESPONSE_LENGTH + 2) ||
	    strncmp((char *)msg, "S=", 2) != 0) {
		/* Packet does not start with "S=" */
		ppp_error("MS-CHAPv2 Success packet is badly formed.");
		return 0;
	}
	msg += 2;
	len -= 2;
	if (len < MS_AUTH_RESPONSE_LENGTH
	    || memcmp(msg, private_, MS_AUTH_RESPONSE_LENGTH)) {
		/* Authenticator Response did not match expected. */
		ppp_error("MS-CHAPv2 mutual authentication failed.");
		return 0;
	}
	/* Authenticator Response matches. */
	msg += MS_AUTH_RESPONSE_LENGTH; /* Eat it */
	len -= MS_AUTH_RESPONSE_LENGTH;
	if ((len >= 3) && !strncmp((char *)msg, " M=", 3)) {
		msg += 3; /* Eat the delimiter */
	} else if (len) {
		/* Packet has extra text which does not begin " M=" */
		ppp_error("MS-CHAPv2 Success packet is badly formed.");
		return 0;
	}
	return 1;
}
/*
 * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.
 */
static void fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len) {
    int ret;
    int treat_as_reject;

    if (id != f->reqid || f->seen_ack)	/* Expected id? */
	return;				/* Nope, toss... */

    if (code == CONFNAK) {
	++f->rnakloops;
	treat_as_reject = (f->rnakloops >= f->maxnakloops);
	if (f->callbacks->nakci == NULL
	    || !(ret = f->callbacks->nakci(f, inp, len, treat_as_reject))) {
	    ppp_error("Received bad configure-nak: %P", inp, len);
	    return;
	}
    } else {
	f->rnakloops = 0;
	if (f->callbacks->rejci == NULL
	    || !(ret = f->callbacks->rejci(f, inp, len))) {
	    ppp_error("Received bad configure-rej: %P", inp, len);
	    return;
	}
    }

    f->seen_ack = 1;

    switch (f->state) {
    case PPP_FSM_CLOSED:
    case PPP_FSM_STOPPED:
	fsm_sdata(f, TERMACK, id, NULL, 0);
	break;

    case PPP_FSM_REQSENT:
    case PPP_FSM_ACKSENT:
	/* They didn't agree to what we wanted - try another request */
	UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
	if (ret < 0)
	    f->state = PPP_FSM_STOPPED;		/* kludge for stopping CCP */
	else
	    fsm_sconfreq(f, 0);		/* Send Configure-Request */
	break;

    case PPP_FSM_ACKRCVD:
	/* Got a Nak/reject when we had already had an Ack?? oh well... */
	UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
	fsm_sconfreq(f, 0);
	f->state = PPP_FSM_REQSENT;
	break;

    case PPP_FSM_OPENED:
	/* Go down and restart negotiation */
	if (f->callbacks->down)
	    (*f->callbacks->down)(f);	/* Inform upper layers */
	fsm_sconfreq(f, 0);		/* Send initial Configure-Request */
	f->state = PPP_FSM_REQSENT;
	break;
    default:
	break;
    }
}
Beispiel #3
0
Datei: upap.c Projekt: crvv/lwip
/*
 * upap_protrej - Peer doesn't speak this protocol.
 *
 * This shouldn't happen.  In any case, pretend lower layer went down.
 */
static void upap_protrej(ppp_pcb *pcb) {

    if (pcb->upap.us_clientstate == UPAPCS_AUTHREQ) {
        ppp_error("PAP authentication failed due to protocol-reject");
        auth_withpeer_fail(pcb, PPP_PAP);
    }
#if PPP_SERVER
    if (pcb->upap.us_serverstate == UPAPSS_LISTEN) {
        ppp_error("PAP authentication of peer failed (protocol-reject)");
        auth_peer_fail(pcb, PPP_PAP);
    }
#endif /* PPP_SERVER */
    upap_lowerdown(pcb);
}
Beispiel #4
0
Datei: upap.c Projekt: crvv/lwip
/*
 * upap_rauthnak - Receive Authenticate-Nak.
 */
static void upap_rauthnak(ppp_pcb *pcb, u_char *inp, int id, int len) {
    u_char msglen;
    char *msg;
    LWIP_UNUSED_ARG(id);

    if (pcb->upap.us_clientstate != UPAPCS_AUTHREQ) /* XXX */
        return;

    /*
     * Parse message.
     */
    if (len < 1) {
        UPAPDEBUG(("pap_rauthnak: ignoring missing msg-length."));
    } else {
        GETCHAR(msglen, inp);
        if (msglen > 0) {
            len -= sizeof (u_char);
            if (len < msglen) {
                UPAPDEBUG(("pap_rauthnak: rcvd short packet."));
                return;
            }
            msg = (char *) inp;
            PRINTMSG(msg, msglen);
        }
    }

    pcb->upap.us_clientstate = UPAPCS_BADAUTH;

    ppp_error("PAP authentication failed");
    auth_withpeer_fail(pcb, PPP_PAP);
}
/*
 * fsm_rconfack - Receive Configure-Ack.
 */
static void fsm_rconfack(fsm *f, int id, u_char *inp, int len) {
    ppp_pcb *pcb = f->pcb;

    if (id != f->reqid || f->seen_ack)		/* Expected id? */
	return;					/* Nope, toss... */
    if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len):
	  (len == 0)) ){
	/* Ack is bad - ignore it */
	ppp_error("Received bad configure-ack: %P", inp, len);
	return;
    }
    f->seen_ack = 1;
    f->rnakloops = 0;

    switch (f->state) {
    case PPP_FSM_CLOSED:
    case PPP_FSM_STOPPED:
	fsm_sdata(f, TERMACK, id, NULL, 0);
	break;

    case PPP_FSM_REQSENT:
	f->state = PPP_FSM_ACKRCVD;
	f->retransmits = pcb->settings.fsm_max_conf_req_transmits;
	break;

    case PPP_FSM_ACKRCVD:
	/* Huh? an extra valid Ack? oh well... */
	UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
	fsm_sconfreq(f, 0);
	f->state = PPP_FSM_REQSENT;
	break;

    case PPP_FSM_ACKSENT:
	UNTIMEOUT(fsm_timeout, f);	/* Cancel timeout */
	f->state = PPP_FSM_OPENED;
	f->retransmits = pcb->settings.fsm_max_conf_req_transmits;
	if (f->callbacks->up)
	    (*f->callbacks->up)(f);	/* Inform upper layers */
	break;

    case PPP_FSM_OPENED:
	/* Go down and restart negotiation */
	if (f->callbacks->down)
	    (*f->callbacks->down)(f);	/* Inform upper layers */
	fsm_sconfreq(f, 0);		/* Send initial Configure-Request */
	f->state = PPP_FSM_REQSENT;
	break;
    default:
	break;
    }
}
Beispiel #6
0
Datei: upap.c Projekt: crvv/lwip
/*
 * upap_timeout - Retransmission timer for sending auth-reqs expired.
 */
static void upap_timeout(void *arg) {
    ppp_pcb *pcb = (ppp_pcb*)arg;

    if (pcb->upap.us_clientstate != UPAPCS_AUTHREQ)
        return;

    if (pcb->upap.us_transmits >= pcb->settings.pap_max_transmits) {
        /* give up in disgust */
        ppp_error("No response to PAP authenticate-requests");
        pcb->upap.us_clientstate = UPAPCS_BADAUTH;
        auth_withpeer_fail(pcb, PPP_PAP);
        return;
    }

    upap_sauthreq(pcb);		/* Send Authenticate-Request */
}
Beispiel #7
0
static void chap_protrej(ppp_pcb *pcb) {

#if PPP_SERVER
	if (pcb->chap_server.flags & TIMEOUT_PENDING) {
		pcb->chap_server.flags &= ~TIMEOUT_PENDING;
		UNTIMEOUT(chap_timeout, pcb);
	}
	if (pcb->chap_server.flags & AUTH_STARTED) {
		pcb->chap_server.flags = 0;
		auth_peer_fail(pcb, PPP_CHAP);
	}
#endif /* PPP_SERVER */
	if ((pcb->chap_client.flags & (AUTH_STARTED|AUTH_DONE)) == AUTH_STARTED) {
		pcb->chap_client.flags &= ~AUTH_STARTED;
		ppp_error("CHAP authentication failed due to protocol-reject");
		auth_withpeer_fail(pcb, PPP_CHAP);
	}
}
Beispiel #8
0
/*
 * chap_verify_response - check whether the peer's response matches
 * what we think it should be.  Returns 1 if it does (authentication
 * succeeded), or 0 if it doesn't.
 */
static int chap_verify_response(ppp_pcb *pcb, const char *name, const char *ourname, int id,
		     const struct chap_digest_type *digest,
		     const unsigned char *challenge, const unsigned char *response,
		     char *message, int message_space) {
	int ok;
	unsigned char secret[MAXSECRETLEN];
	int secret_len;

	/* Get the secret that the peer is supposed to know */
	if (!get_secret(pcb, name, ourname, (char *)secret, &secret_len, 1)) {
		ppp_error("No CHAP secret found for authenticating %q", name);
		return 0;
	}
	ok = digest->verify_response(pcb, id, name, secret, secret_len, challenge,
				     response, message, message_space);
	memset(secret, 0, sizeof(secret));

	return ok;
}
Beispiel #9
0
/*
 * chap_auth_with_peer - Prepare to authenticate ourselves to the peer.
 * There isn't much to do until we receive a challenge.
 */
void chap_auth_with_peer(ppp_pcb *pcb, const char *our_name, int digest_code) {
	const struct chap_digest_type *dp;
	int i;

	if(NULL == our_name)
		return;

	if (pcb->chap_client.flags & AUTH_STARTED) {
		ppp_error("CHAP: authentication with peer already started!");
		return;
	}
	for (i = 0; (dp = chap_digests[i]) != NULL; ++i)
		if (dp->code == digest_code)
			break;

	if (dp == NULL)
		ppp_fatal("CHAP digest 0x%x requested but not available",
		      digest_code);

	pcb->chap_client.digest = dp;
	pcb->chap_client.name = our_name;
	pcb->chap_client.flags |= AUTH_STARTED;
}
Beispiel #10
0
/*
 * chap_auth_peer - Start authenticating the peer.
 * If the lower layer is already up, we start sending challenges,
 * otherwise we wait for the lower layer to come up.
 */
void chap_auth_peer(ppp_pcb *pcb, const char *our_name, int digest_code) {
	const struct chap_digest_type *dp;
	int i;

	if (pcb->chap_server.flags & AUTH_STARTED) {
		ppp_error("CHAP: peer authentication already started!");
		return;
	}
	for (i = 0; (dp = chap_digests[i]) != NULL; ++i)
		if (dp->code == digest_code)
			break;
	if (dp == NULL)
		ppp_fatal("CHAP digest 0x%x requested but not available",
		      digest_code);

	pcb->chap_server.digest = dp;
	pcb->chap_server.name = our_name;
	/* Start with a random ID value */
	pcb->chap_server.id = magic();
	pcb->chap_server.flags |= AUTH_STARTED;
	if (pcb->chap_server.flags & LOWERUP)
		chap_timeout(pcb);
}
Beispiel #11
0
static void chap_handle_status(ppp_pcb *pcb, int code, int id,
		   unsigned char *pkt, int len) {
	const char *msg = NULL;
	LWIP_UNUSED_ARG(id);

	if ((pcb->chap_client.flags & (AUTH_DONE|AUTH_STARTED|LOWERUP))
	    != (AUTH_STARTED|LOWERUP))
		return;
	pcb->chap_client.flags |= AUTH_DONE;

	if (code == CHAP_SUCCESS) {
		/* used for MS-CHAP v2 mutual auth, yuck */
		if (pcb->chap_client.digest->check_success != NULL) {
			if (!(*pcb->chap_client.digest->check_success)(pcb, pkt, len, pcb->chap_client.priv))
				code = CHAP_FAILURE;
		} else
			msg = "CHAP authentication succeeded";
	} else {
		if (pcb->chap_client.digest->handle_failure != NULL)
			(*pcb->chap_client.digest->handle_failure)(pcb, pkt, len);
		else
			msg = "CHAP authentication failed";
	}
	if (msg) {
		if (len > 0)
			ppp_info("%s: %.*v", msg, len, pkt);
		else
			ppp_info("%s", msg);
	}
	if (code == CHAP_SUCCESS)
		auth_withpeer_success(pcb, PPP_CHAP, pcb->chap_client.digest->code);
	else {
		pcb->chap_client.flags |= AUTH_FAILED;
		ppp_error("CHAP authentication failed");
		auth_withpeer_fail(pcb, PPP_CHAP);
	}
}
Beispiel #12
0
static void chapms_handle_failure(ppp_pcb *pcb, unsigned char *inp, int len) {
	int err;
	const char *p;
	char msg[64];
	LWIP_UNUSED_ARG(pcb);

	/* We want a null-terminated string for strxxx(). */
	len = LWIP_MIN(len, 63);
	MEMCPY(msg, inp, len);
	msg[len] = 0;
	p = msg;

	/*
	 * Deal with MS-CHAP formatted failure messages; just print the
	 * M=<message> part (if any).  For MS-CHAP we're not really supposed
	 * to use M=<message>, but it shouldn't hurt.  See
	 * chapms[2]_verify_response.
	 */
	if (!strncmp(p, "E=", 2))
		err = strtol(p+2, NULL, 10); /* Remember the error code. */
	else
		goto print_msg; /* Message is badly formatted. */

	if (len && ((p = strstr(p, " M=")) != NULL)) {
		/* M=<message> field found. */
		p += 3;
	} else {
		/* No M=<message>; use the error code. */
		switch (err) {
		case MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS:
			p = "E=646 Restricted logon hours";
			break;

		case MS_CHAP_ERROR_ACCT_DISABLED:
			p = "E=647 Account disabled";
			break;

		case MS_CHAP_ERROR_PASSWD_EXPIRED:
			p = "E=648 Password expired";
			break;

		case MS_CHAP_ERROR_NO_DIALIN_PERMISSION:
			p = "E=649 No dialin permission";
			break;

		case MS_CHAP_ERROR_AUTHENTICATION_FAILURE:
			p = "E=691 Authentication failure";
			break;

		case MS_CHAP_ERROR_CHANGING_PASSWORD:
			/* Should never see this, we don't support Change Password. */
			p = "E=709 Error changing password";
			break;

		default:
			ppp_error("Unknown MS-CHAP authentication failure: %.*v",
			      len, inp);
			return;
		}
	}
print_msg:
	if (p != NULL)
		ppp_error("MS-CHAP authentication failed: %v", p);
}