Ejemplo n.º 1
0
static int mschapv1_encode(RADIUS_PACKET *packet, VALUE_PAIR **request,
			   char const *password)
{
	unsigned int i;
	uint8_t *p;
	VALUE_PAIR *challenge, *reply;
	uint8_t nthash[16];

	fr_pair_delete_by_num(&packet->vps, PW_MSCHAP_CHALLENGE, VENDORPEC_MICROSOFT, TAG_ANY);
	fr_pair_delete_by_num(&packet->vps, PW_MSCHAP_RESPONSE, VENDORPEC_MICROSOFT, TAG_ANY);

	challenge = fr_pair_afrom_num(packet, PW_MSCHAP_CHALLENGE, VENDORPEC_MICROSOFT);
	if (!challenge) {
		return 0;
	}

	fr_pair_add(request, challenge);
	challenge->vp_length = 8;
	challenge->vp_octets = p = talloc_array(challenge, uint8_t, challenge->vp_length);
	for (i = 0; i < challenge->vp_length; i++) {
		p[i] = fr_rand();
	}

	reply = fr_pair_afrom_num(packet, PW_MSCHAP_RESPONSE, VENDORPEC_MICROSOFT);
	if (!reply) {
		return 0;
	}

	fr_pair_add(request, reply);
	reply->vp_length = 50;
	reply->vp_octets = p = talloc_array(reply, uint8_t, reply->vp_length);
	memset(p, 0, reply->vp_length);

	p[1] = 0x01; /* NT hash */

	if (mschap_ntpwdhash(nthash, password) < 0) {
		return 0;
	}

	smbdes_mschap(nthash, challenge->vp_octets, p + 26);
	return 1;
}
Ejemplo n.º 2
0
static int mschapv1_encode(RADIUS_PACKET *packet, VALUE_PAIR **request,
                           char const *password)
{
    unsigned int i;
    uint8_t *p;
    VALUE_PAIR *challenge, *response;
    uint8_t nthash[16];

    challenge = paircreate(packet, PW_MSCHAP_CHALLENGE, VENDORPEC_MICROSOFT);
    if (!challenge) {
        fprintf(stderr, "GOT IT %d!\n", __LINE__);
        return 0;
    }

    pairadd(request, challenge);
    challenge->length = 8;
    challenge->vp_octets = p = talloc_array(challenge, uint8_t, challenge->length);
    for (i = 0; i < challenge->length; i++) {
        p[i] = fr_rand();
    }

    response = paircreate(packet, PW_MSCHAP_RESPONSE, VENDORPEC_MICROSOFT);
    if (!response) {
        fprintf(stderr, "GOT IT %d!\n", __LINE__);
        return 0;
    }

    pairadd(request, response);
    response->length = 50;
    response->vp_octets = p = talloc_array(response, uint8_t, response->length);
    memset(p, 0, response->length);

    p[1] = 0x01; /* NT hash */

    mschap_ntpwdhash(nthash, password);

    smbdes_mschap(nthash, challenge->vp_octets,
                  p + 26);
    return 1;
}
Ejemplo n.º 3
0
static int mschapv1_encode(VALUE_PAIR **request, const char *password)
{
	unsigned int i;
	VALUE_PAIR *challenge, *response;
	uint8_t nthash[16];

	challenge = paircreate(PW_MSCHAP_CHALLENGE, VENDORPEC_MICROSOFT, PW_TYPE_OCTETS);
	if (!challenge) {
		fprintf(stderr, "GOT IT %d!\n", __LINE__);
		return 0;
	}

	pairadd(request, challenge);
	challenge->length = 8;
	for (i = 0; i < challenge->length; i++) {
		challenge->vp_octets[i] = fr_rand();
	}

	response = paircreate(PW_MSCHAP_RESPONSE, VENDORPEC_MICROSOFT, PW_TYPE_OCTETS);
	if (!response) {
		fprintf(stderr, "GOT IT %d!\n", __LINE__);
		return 0;
	}

	pairadd(request, response);
	response->length = 50;
	memset(response->vp_octets, 0, response->length);

	response->vp_octets[1] = 0x01; /* NT hash */

	mschap_ntpwdhash(nthash, password);

	smbdes_mschap(nthash, challenge->vp_octets,
		      response->vp_octets + 26);
	return 1;
}
Ejemplo n.º 4
0
/*
 *	Do the MS-CHAP stuff.
 *
 *	This function is here so that all of the MS-CHAP related
 *	authentication is in one place, and we can perhaps later replace
 *	it with code to call winbindd, or something similar.
 */
static int do_mschap(rlm_mschap_t *inst,
		     REQUEST *request, VALUE_PAIR *password,
		     uint8_t *challenge, uint8_t *response,
		     uint8_t *nthashhash, int do_ntlm_auth)
{
	uint8_t		calculated[24];

	/*
	 *	Do normal authentication.
	 */
	if (!do_ntlm_auth) {
		/*
		 *	No password: can't do authentication.
		 */
		if (!password) {
			RDEBUG2("FAILED: No NT/LM-Password.  Cannot perform authentication.");
			return -1;
		}

		smbdes_mschap(password->vp_strvalue, challenge, calculated);
		if (memcmp(response, calculated, 24) != 0) {
			return -1;
		}

		/*
		 *	If the password exists, and is an NT-Password,
		 *	then calculate the hash of the NT hash.  Doing this
		 *	here minimizes work for later.
		 */
		if (password && (password->attribute == PW_NT_PASSWORD)) {
			fr_md4_calc(nthashhash, password->vp_octets, 16);
		} else {
			memset(nthashhash, 0, 16);
		}
	} else {		/* run ntlm_auth */
		int	result;
		char	buffer[256];

		memset(nthashhash, 0, 16);

		/*
		 *	Run the program, and expect that we get 16
		 */
		result = radius_exec_program(inst->ntlm_auth, request,
					     TRUE, /* wait */
					     buffer, sizeof(buffer),
					     NULL, NULL, 1);
		if (result != 0) {
			RDEBUG2("External script failed.");
			return -1;
		}

		/*
		 *	Parse the answer as an nthashhash.
		 *
		 *	ntlm_auth currently returns:
		 *	NT_KEY: 000102030405060708090a0b0c0d0e0f
		 */
		if (memcmp(buffer, "NT_KEY: ", 8) != 0) {
			RDEBUG2("Invalid output from ntlm_auth: expecting NT_KEY");
			return -1;
		}

		/*
		 *	Check the length.  It should be at least 32,
		 *	with an LF at the end.
		 */
		if (strlen(buffer + 8) < 32) {
			RDEBUG2("Invalid output from ntlm_auth: NT_KEY has unexpected length");
			return -1;
		}

		/*
		 *	Update the NT hash hash, from the NT key.
		 */
		if (fr_hex2bin(buffer + 8, nthashhash, 16) != 16) {
			RDEBUG2("Invalid output from ntlm_auth: NT_KEY has non-hex values");
			return -1;
		}
	}

	return 0;
}
/*
 *	Do the MS-CHAP stuff.
 *
 *	This function is here so that all of the MS-CHAP related
 *	authentication is in one place, and we can perhaps later replace
 *	it with code to call winbindd, or something similar.
 */
static int do_mschap(rlm_mschap_t *inst,
		     REQUEST *request, VALUE_PAIR *password,
		     uint8_t *challenge, uint8_t *response,
		     uint8_t *nthashhash, int do_ntlm_auth)
{
	uint8_t		calculated[24];

	/*
	 *	Do normal authentication.
	 */
	if (!do_ntlm_auth) {
		/*
		 *	No password: can't do authentication.
		 */
		if (!password) {
			RDEBUG2("FAILED: No NT/LM-Password.  Cannot perform authentication.");
			return -1;
		}

		smbdes_mschap(password->vp_strvalue, challenge, calculated);
		if (rad_digest_cmp(response, calculated, 24) != 0) {
			return -1;
		}

		/*
		 *	If the password exists, and is an NT-Password,
		 *	then calculate the hash of the NT hash.  Doing this
		 *	here minimizes work for later.
		 */
		if (password && (password->attribute == PW_NT_PASSWORD)) {
			fr_md4_calc(nthashhash, password->vp_octets, 16);
		} else {
			memset(nthashhash, 0, 16);
		}
	} else {		/* run ntlm_auth */
		int	result;
		char	buffer[256];

		memset(nthashhash, 0, 16);

		/*
		 *	Run the program, and expect that we get 16
		 */
		result = radius_exec_program(inst->ntlm_auth, request,
					     TRUE, /* wait */
					     buffer, sizeof(buffer),
					     NULL, NULL, 1);
		if (result != 0) {
			char *p;
			VALUE_PAIR *vp = NULL;

			RDEBUG2("External script failed.");

			vp = pairmake("Module-Failure-Message", "", T_OP_EQ);
			if (!vp) {
				radlog_request(L_ERR, 0, request, "No memory to allocate Module-Failure-Message");
				return RLM_MODULE_FAIL;
			}

			p = strchr(buffer, '\n');
			if (p) *p = '\0';
			snprintf(vp->vp_strvalue, sizeof(vp->vp_strvalue),
				"%s: External script says %s",
				 inst->xlat_name, buffer);
			vp->length = strlen(vp->vp_strvalue);
			pairadd(&request->packet->vps, vp);
			return -1;
		}

		/*
		 *	Parse the answer as an nthashhash.
		 *
		 *	ntlm_auth currently returns:
		 *	NT_KEY: 000102030405060708090a0b0c0d0e0f
		 */
		if (memcmp(buffer, "NT_KEY: ", 8) != 0) {
			RDEBUG2("Invalid output from ntlm_auth: expecting NT_KEY");
			return -1;
		}

		/*
		 *	Check the length.  It should be at least 32,
		 *	with an LF at the end.
		 */
		if (strlen(buffer + 8) < 32) {
			RDEBUG2("Invalid output from ntlm_auth: NT_KEY has unexpected length");
			return -1;
		}

		/*
		 *	Update the NT hash hash, from the NT key.
		 */
		if (fr_hex2bin(buffer + 8, nthashhash, 16) != 16) {
			RDEBUG2("Invalid output from ntlm_auth: NT_KEY has non-hex values");
			return -1;
		}
	}

	return 0;
}
Ejemplo n.º 6
0
/*
 *	Do the MS-CHAP stuff.
 *
 *	This function is here so that all of the MS-CHAP related
 *	authentication is in one place, and we can perhaps later replace
 *	it with code to call winbindd, or something similar.
 */
static int do_mschap(rlm_mschap_t *inst,
		     REQUEST *request, VALUE_PAIR *password,
		     uint8_t *challenge, uint8_t *response,
		     uint8_t *nthashhash)
{
	int		do_ntlm_auth = 0;
	uint8_t		calculated[24];
	VALUE_PAIR	*vp = NULL;

	/*
	 *	If we have ntlm_auth configured, use it unless told
	 *	otherwise
	 */
	if (inst->ntlm_auth) do_ntlm_auth = 1;

	/*
	 *	If we have an ntlm_auth configuration, then we may
	 *	want to use it.
	 */
	vp = pairfind(request->config_items,
		      PW_MS_CHAP_USE_NTLM_AUTH);
	if (vp) do_ntlm_auth = vp->vp_integer;

	/*
	 *	No ntlm_auth configured, attribute to tell us to
	 *	use it exists, and we're told to use it.  We don't
	 *	know what to do...
	 */
	if (!inst->ntlm_auth && do_ntlm_auth) {
		RDEBUG2("Asked to use ntlm_auth, but it was not configured in the mschap{} section.");
		return -1;
	}

	/*
	 *	Do normal authentication.
	 */
	if (!do_ntlm_auth) {
		/*
		 *	No password: can't do authentication.
		 */
		if (!password) {
			RDEBUG2("FAILED: No NT/LM-Password.  Cannot perform authentication.");
			return -1;
		}

		smbdes_mschap(password->vp_strvalue, challenge, calculated);
		if (memcmp(response, calculated, 24) != 0) {
			return -1;
		}

		/*
		 *	If the password exists, and is an NT-Password,
		 *	then calculate the hash of the NT hash.  Doing this
		 *	here minimizes work for later.
		 */
		if (password && (password->attribute == PW_NT_PASSWORD)) {
			fr_md4_calc(nthashhash, password->vp_octets, 16);
		} else {
			memset(nthashhash, 0, 16);
		}
	} else {		/* run ntlm_auth */
		int	result;
		char	buffer[256];

		memset(nthashhash, 0, 16);

		/*
		 *	Run the program, and expect that we get 16
		 */
		result = radius_exec_program(inst->ntlm_auth, request,
					     TRUE, /* wait */
					     buffer, sizeof(buffer),
					     NULL, NULL, 1);
		if (result != 0) {
			RDEBUG2("External script failed.");
			return -1;
		}

		/*
		 *	Parse the answer as an nthashhash.
		 *
		 *	ntlm_auth currently returns:
		 *	NT_KEY: 000102030405060708090a0b0c0d0e0f
		 */
		if (memcmp(buffer, "NT_KEY: ", 8) != 0) {
			RDEBUG2("Invalid output from ntlm_auth: expecting NT_KEY");
			return -1;
		}

		/*
		 *	Check the length.  It should be at least 32,
		 *	with an LF at the end.
		 */
		if (strlen(buffer + 8) < 32) {
			RDEBUG2("Invalid output from ntlm_auth: NT_KEY has unexpected length");
			return -1;
		}

		/*
		 *	Update the NT hash hash, from the NT key.
		 */
		if (fr_hex2bin(buffer + 8, nthashhash, 16) != 16) {
			RDEBUG2("Invalid output from ntlm_auth: NT_KEY has non-hex values");
			return -1;
		}
	}

	return 0;
}