mirror of
https://github.com/openbsd/src.git
synced 2026-06-17 23:03:29 +02:00
Add length checks for the Port-Message and State attributes in the
handling of Access-Challenge. The problem reported by Steve Caffrey. ok sthen@
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: login_radius.c,v 1.10 2021/01/02 20:32:20 millert Exp $ */
|
/* $OpenBSD: login_radius.c,v 1.11 2026/06/11 04:55:12 yasuoka Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1996, 1997 Berkeley Software Design, Inc. All rights reserved.
|
* Copyright (c) 1996, 1997 Berkeley Software Design, Inc. All rights reserved.
|
||||||
@@ -179,8 +179,11 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
emsg = NULL;
|
emsg = NULL;
|
||||||
|
|
||||||
c = raddauth(username, class, style,
|
if (strcmp(service, "login") != 0)
|
||||||
strcmp(service, "login") ? challenge : NULL, password, &emsg);
|
c = raddauth(username, class, style, challenge,
|
||||||
|
sizeof(challenge), password, &emsg);
|
||||||
|
else
|
||||||
|
c = raddauth(username, class, style, NULL, 0, password, &emsg);
|
||||||
|
|
||||||
if (c == 0) {
|
if (c == 0) {
|
||||||
if (*challenge == '\0') {
|
if (*challenge == '\0') {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: login_radius.h,v 1.1 2003/07/06 21:54:38 deraadt Exp $ */
|
/* $OpenBSD: login_radius.h,v 1.2 2026/06/11 04:55:12 yasuoka Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003 Theo de Raadt <deraadt@openbsd.org>
|
* Copyright (c) 2003 Theo de Raadt <deraadt@openbsd.org>
|
||||||
@@ -18,4 +18,4 @@
|
|||||||
|
|
||||||
int
|
int
|
||||||
raddauth(char *username, char *class, char *style, char *challenge,
|
raddauth(char *username, char *class, char *style, char *challenge,
|
||||||
char *password, char **emsg);
|
size_t challlen, char *password, char **emsg);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: raddauth.c,v 1.33 2024/07/18 02:45:31 yasuoka Exp $ */
|
/* $OpenBSD: raddauth.c,v 1.34 2026/06/11 04:55:12 yasuoka Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1996, 1997 Berkeley Software Design, Inc. All rights reserved.
|
* Copyright (c) 1996, 1997 Berkeley Software Design, Inc. All rights reserved.
|
||||||
@@ -105,7 +105,7 @@
|
|||||||
#define PW_PASSWORD 2
|
#define PW_PASSWORD 2
|
||||||
#define PW_CLIENT_ID 4
|
#define PW_CLIENT_ID 4
|
||||||
#define PW_CLIENT_PORT_ID 5
|
#define PW_CLIENT_PORT_ID 5
|
||||||
#define PW_PORT_MESSAGE 18
|
#define PW_REPLY_MESSAGE 18
|
||||||
#define PW_STATE 24
|
#define PW_STATE 24
|
||||||
#define PW_MSG_AUTH 80
|
#define PW_MSG_AUTH 80
|
||||||
|
|
||||||
@@ -136,8 +136,8 @@ typedef struct {
|
|||||||
void servtimeout(int);
|
void servtimeout(int);
|
||||||
in_addr_t get_ipaddr(char *);
|
in_addr_t get_ipaddr(char *);
|
||||||
in_addr_t gethost(void);
|
in_addr_t gethost(void);
|
||||||
int rad_recv(char *, char *, u_char *);
|
int rad_recv(char *, char *, size_t, u_char *);
|
||||||
void parse_challenge(auth_hdr_t *, char *, char *);
|
void parse_challenge(auth_hdr_t *, char *, char *, size_t);
|
||||||
void rad_request(u_char, char *, char *, int, char *, char *);
|
void rad_request(u_char, char *, char *, int, char *, char *);
|
||||||
void getsecret(void);
|
void getsecret(void);
|
||||||
|
|
||||||
@@ -147,7 +147,7 @@ void getsecret(void);
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
raddauth(char *username, char *class, char *style, char *challenge,
|
raddauth(char *username, char *class, char *style, char *challenge,
|
||||||
char *password, char **emsg)
|
size_t challlen, char *password, char **emsg)
|
||||||
{
|
{
|
||||||
static char _pwstate[1024];
|
static char _pwstate[1024];
|
||||||
u_char req_id;
|
u_char req_id;
|
||||||
@@ -292,7 +292,7 @@ retry:
|
|||||||
rad_request(req_id, userstyle, passwd, auth_port, vector,
|
rad_request(req_id, userstyle, passwd, auth_port, vector,
|
||||||
pwstate);
|
pwstate);
|
||||||
|
|
||||||
switch (i = rad_recv(_pwstate, challenge, vector)) {
|
switch (i = rad_recv(_pwstate, challenge, challlen, vector)) {
|
||||||
case PW_AUTHENTICATION_ACK:
|
case PW_AUTHENTICATION_ACK:
|
||||||
/*
|
/*
|
||||||
* Make sure we don't think a challenge was issued.
|
* Make sure we don't think a challenge was issued.
|
||||||
@@ -461,7 +461,7 @@ rad_request(u_char id, char *name, char *password, int port, char *vector,
|
|||||||
* Receive UDP responses from the radius server
|
* Receive UDP responses from the radius server
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
rad_recv(char *state, char *challenge, u_char *req_vector)
|
rad_recv(char *state, char *challenge, size_t challlen, u_char *req_vector)
|
||||||
{
|
{
|
||||||
auth_hdr_t auth;
|
auth_hdr_t auth;
|
||||||
socklen_t salen;
|
socklen_t salen;
|
||||||
@@ -498,7 +498,7 @@ rad_recv(char *state, char *challenge, u_char *req_vector)
|
|||||||
errx(1, "shared secret incorrect");
|
errx(1, "shared secret incorrect");
|
||||||
|
|
||||||
if (auth.code == PW_ACCESS_CHALLENGE)
|
if (auth.code == PW_ACCESS_CHALLENGE)
|
||||||
parse_challenge(&auth, state, challenge);
|
parse_challenge(&auth, state, challenge, challlen);
|
||||||
|
|
||||||
return (auth.code);
|
return (auth.code);
|
||||||
}
|
}
|
||||||
@@ -607,7 +607,8 @@ servtimeout(int signo)
|
|||||||
* Parse a challenge received from the server
|
* Parse a challenge received from the server
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
parse_challenge(auth_hdr_t *authhdr, char *state, char *challenge)
|
parse_challenge(auth_hdr_t *authhdr, char *state, char *challenge,
|
||||||
|
size_t challlen)
|
||||||
{
|
{
|
||||||
int length;
|
int length;
|
||||||
int attribute, attribute_len;
|
int attribute, attribute_len;
|
||||||
@@ -619,13 +620,21 @@ parse_challenge(auth_hdr_t *authhdr, char *state, char *challenge)
|
|||||||
*state = 0;
|
*state = 0;
|
||||||
|
|
||||||
while (length > 0) {
|
while (length > 0) {
|
||||||
|
if (length < 2)
|
||||||
|
errx(1, "bogus auth packet from server");
|
||||||
attribute = *ptr++;
|
attribute = *ptr++;
|
||||||
attribute_len = *ptr++;
|
attribute_len = *ptr++;
|
||||||
|
if (attribute_len < 2 || length < attribute_len)
|
||||||
|
errx(1, "bogus attribute in auth packet from server");
|
||||||
length -= attribute_len;
|
length -= attribute_len;
|
||||||
attribute_len -= 2;
|
attribute_len -= 2;
|
||||||
|
|
||||||
switch (attribute) {
|
switch (attribute) {
|
||||||
case PW_PORT_MESSAGE:
|
case PW_REPLY_MESSAGE:
|
||||||
|
if (attribute_len < 1)
|
||||||
|
errx(1, "bogus reply-message from server");
|
||||||
|
if (attribute_len > challlen)
|
||||||
|
errx(1, "reply-message too long");
|
||||||
if (challenge) {
|
if (challenge) {
|
||||||
memcpy(challenge, ptr, attribute_len);
|
memcpy(challenge, ptr, attribute_len);
|
||||||
challenge[attribute_len] = '\0';
|
challenge[attribute_len] = '\0';
|
||||||
@@ -633,6 +642,10 @@ parse_challenge(auth_hdr_t *authhdr, char *state, char *challenge)
|
|||||||
printf("%.*s", attribute_len, ptr);
|
printf("%.*s", attribute_len, ptr);
|
||||||
break;
|
break;
|
||||||
case PW_STATE:
|
case PW_STATE:
|
||||||
|
if (attribute_len < 1)
|
||||||
|
errx(1, "bogus reply message from server");
|
||||||
|
if (attribute_len > AUTH_VECTOR_LEN)
|
||||||
|
errx(1, "state too long");
|
||||||
memcpy(state, ptr, attribute_len);
|
memcpy(state, ptr, attribute_len);
|
||||||
state[attribute_len] = '\0';
|
state[attribute_len] = '\0';
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user