diff options
-rw-r--r-- | usr.sbin/ppp/ppp/Makefile | 15 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/alias.c | 137 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/alias.h | 5 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/alias_db.c | 215 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/alias_local.h | 16 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/alias_pptp.c | 57 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/radlib.c | 127 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/radlib.h | 57 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/radlib_private.h | 8 |
9 files changed, 576 insertions, 61 deletions
diff --git a/usr.sbin/ppp/ppp/Makefile b/usr.sbin/ppp/ppp/Makefile index cf19075d676..a4569e93c17 100644 --- a/usr.sbin/ppp/ppp/Makefile +++ b/usr.sbin/ppp/ppp/Makefile @@ -1,15 +1,16 @@ -# $OpenBSD: Makefile,v 1.15 2000/06/23 09:47:04 brian Exp $ +# $OpenBSD: Makefile,v 1.16 2000/08/13 22:05:47 brian Exp $ PROG= ppp SRCS= alias.c alias_cuseeme.c alias_db.c alias_ftp.c alias_irc.c \ - alias_nbt.c alias_pptp.c alias_proxy.c alias_util.c acf.c arp.c \ - async.c auth.c bundle.c cbcp.c ccp.c chap.c chap_ms.c chat.c \ - command.c datalink.c deflate.c defs.c exec.c filter.c fsm.c hdlc.c \ - id.c iface.c ip.c ipcp.c iplist.c lcp.c link.c log.c lqr.c main.c \ - mbuf.c mp.c nat_cmd.c pap.c physical.c pred.c probe.c prompt.c \ + alias_nbt.c alias_pptp.c alias_proxy.c alias_smedia.c alias_util.c \ + acf.c arp.c async.c auth.c bundle.c cbcp.c ccp.c chap.c chap_ms.c \ + chat.c command.c datalink.c deflate.c defs.c exec.c filter.c fsm.c \ + hdlc.c id.c iface.c ip.c ipcp.c iplist.c lcp.c link.c log.c lqr.c \ + main.c mbuf.c mp.c nat_cmd.c pap.c physical.c pred.c probe.c prompt.c \ proto.c radius.c radlib.c route.c server.c sig.c slcompress.c \ systems.c sync.c tcp.c throughput.c timer.c tty.c tun.c udp.c vjcomp.c -CFLAGS+=-Wall -DHAVE_DES -DNO_FW_PUNCH -DNOI4B -DNONETGRAPH -DLOCALNAT -DLOCALRAD +CFLAGS+=-Wall -DHAVE_DES -DNO_FW_PUNCH -DNOI4B -DNONETGRAPH +CFLAGS+=-DLOCALNAT -DLOCALRAD LDADD+= -ldes -lutil -lz DPADD+= ${LIBDES} ${LIBUTIL} ${LIBZ} BINMODE=4554 diff --git a/usr.sbin/ppp/ppp/alias.c b/usr.sbin/ppp/ppp/alias.c index ae3c1eb5f83..10f33e6d1dc 100644 --- a/usr.sbin/ppp/ppp/alias.c +++ b/usr.sbin/ppp/ppp/alias.c @@ -76,12 +76,16 @@ Version 2.3 Dec 1998 (dillon) - Major bounds checking additions, see FreeBSD/CVS - Version 3.1 May, 2000 (eds) + Version 3.1 May, 2000 (salander) - Added hooks to handle PPTP. + Version 3.2 July, 2000 (salander and satoh) + - Added PacketUnaliasOut routine. + - Added hooks to handle RTSP/RTP. + See HISTORY file for additional revisions. - $OpenBSD: alias.c,v 1.8 2000/06/23 09:47:04 brian Exp $ + $OpenBSD: alias.c,v 1.9 2000/08/13 22:05:47 brian Exp $ */ #include <sys/types.h> @@ -102,6 +106,8 @@ #define IRC_CONTROL_PORT_NUMBER_1 6667 #define IRC_CONTROL_PORT_NUMBER_2 6668 #define CUSEEME_PORT_NUMBER 7648 +#define RTSP_CONTROL_PORT_NUMBER_1 554 +#define RTSP_CONTROL_PORT_NUMBER_2 7070 #define PPTP_CONTROL_PORT_NUMBER 1723 @@ -1112,6 +1118,11 @@ TcpAliasOut(struct ip *pip, int maxpacketsize) else if (ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_1 || ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_2) AliasHandleIrcOut(pip, link, maxpacketsize); + else if (ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_1 + || ntohs(tc->th_sport) == RTSP_CONTROL_PORT_NUMBER_1 + || ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_2 + || ntohs(tc->th_sport) == RTSP_CONTROL_PORT_NUMBER_2) + AliasHandleRtspOut(pip, link, maxpacketsize); else if (ntohs(tc->th_dport) == PPTP_CONTROL_PORT_NUMBER || ntohs(tc->th_sport) == PPTP_CONTROL_PORT_NUMBER) AliasHandlePptpOut(pip, link); @@ -1236,6 +1247,7 @@ FragmentOut(struct ip *pip) PacketAliasFragmentIn() PacketAliasIn() PacketAliasOut() + PacketUnaliasOut() (prototypes in alias.h) */ @@ -1465,3 +1477,124 @@ PacketAliasOut(char *ptr, /* valid IP packet */ SetDefaultAliasAddress(addr_save); return(iresult); } + +int +PacketUnaliasOut(char *ptr, /* valid IP packet */ + int maxpacketsize /* for error checking */ + ) +{ + struct ip *pip; + struct icmp *ic; + struct udphdr *ud; + struct tcphdr *tc; + struct alias_link *link; + int iresult = PKT_ALIAS_IGNORED; + + pip = (struct ip *) ptr; + + /* Defense against mangled packets */ + if (ntohs(pip->ip_len) > maxpacketsize + || (pip->ip_hl<<2) > maxpacketsize) + return(iresult); + + ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); + tc = (struct tcphdr *) ud; + ic = (struct icmp *) ud; + + /* Find a link */ + if (pip->ip_p == IPPROTO_UDP) + link = QueryUdpTcpIn(pip->ip_dst, pip->ip_src, + ud->uh_dport, ud->uh_sport, + IPPROTO_UDP); + else if (pip->ip_p == IPPROTO_TCP) + link = QueryUdpTcpIn(pip->ip_dst, pip->ip_src, + tc->th_dport, tc->th_sport, + IPPROTO_TCP); + else if (pip->ip_p == IPPROTO_ICMP) + link = FindIcmpIn(pip->ip_dst, pip->ip_src, ic->icmp_id); + else + link = NULL; + + /* Change it from an aliased packet to an unaliased packet */ + if (link != NULL) + { + if (pip->ip_p == IPPROTO_UDP || pip->ip_p == IPPROTO_TCP) + { + u_short *sptr; + int accumulate; + struct in_addr original_address; + u_short original_port; + + original_address = GetOriginalAddress(link); + original_port = GetOriginalPort(link); + + /* Adjust TCP/UDP checksum */ + sptr = (u_short *) &(pip->ip_src); + accumulate = *sptr++; + accumulate += *sptr; + sptr = (u_short *) &original_address; + accumulate -= *sptr++; + accumulate -= *sptr; + + if (pip->ip_p == IPPROTO_UDP) { + accumulate += ud->uh_sport; + accumulate -= original_port; + ADJUST_CHECKSUM(accumulate, ud->uh_sum) + } else { + accumulate += tc->th_sport; + accumulate -= original_port; + ADJUST_CHECKSUM(accumulate, tc->th_sum) + } + + /* Adjust IP checksum */ + DifferentialChecksum(&pip->ip_sum, + (u_short *) &original_address, + (u_short *) &pip->ip_src, + 2); + + /* Un-alias source address and port number */ + pip->ip_src = original_address; + if (pip->ip_p == IPPROTO_UDP) + ud->uh_sport = original_port; + else + tc->th_sport = original_port; + + iresult = PKT_ALIAS_OK; + + } else if (pip->ip_p == IPPROTO_ICMP) { + + u_short *sptr; + int accumulate; + struct in_addr original_address; + u_short original_id; + + original_address = GetOriginalAddress(link); + original_id = GetOriginalPort(link); + + /* Adjust ICMP checksum */ + sptr = (u_short *) &(pip->ip_src); + accumulate = *sptr++; + accumulate += *sptr; + sptr = (u_short *) &original_address; + accumulate -= *sptr++; + accumulate -= *sptr; + accumulate += ic->icmp_id; + accumulate -= original_id; + ADJUST_CHECKSUM(accumulate, ic->icmp_cksum) + + /* Adjust IP checksum */ + DifferentialChecksum(&pip->ip_sum, + (u_short *) &original_address, + (u_short *) &pip->ip_src, + 2); + + /* Un-alias source address and port number */ + pip->ip_src = original_address; + ic->icmp_id = original_id; + + iresult = PKT_ALIAS_OK; + } + } + return(iresult); + +} diff --git a/usr.sbin/ppp/ppp/alias.h b/usr.sbin/ppp/ppp/alias.h index 4ab16823cdb..86760b3ad59 100644 --- a/usr.sbin/ppp/ppp/alias.h +++ b/usr.sbin/ppp/ppp/alias.h @@ -7,7 +7,7 @@ This software is placed into the public domain with no restrictions on its distribution. - $OpenBSD: alias.h,v 1.6 2000/06/23 09:47:04 brian Exp $ + $OpenBSD: alias.h,v 1.7 2000/08/13 22:05:47 brian Exp $ */ @@ -44,6 +44,9 @@ struct alias_link; extern int PacketAliasOut(char *, int maxpacketsize); + extern int + PacketUnaliasOut(char *, int maxpacketsize); + /* Port and Address Redirection */ extern struct alias_link * PacketAliasRedirectPort(struct in_addr, u_short, diff --git a/usr.sbin/ppp/ppp/alias_db.c b/usr.sbin/ppp/ppp/alias_db.c index eddce44f422..19ddbf65469 100644 --- a/usr.sbin/ppp/ppp/alias_db.c +++ b/usr.sbin/ppp/ppp/alias_db.c @@ -103,9 +103,19 @@ version of PacketAliasPermanentLink(). The second function implements static network address translation. + Version 3.2: July, 2000 (salander and satoh) + Added FindNewPortGroup to get contiguous range of port values. + + Added QueryUdpTcpIn and QueryUdpTcpOut to look for an aliasing + link but not actually add one. + + Added FindRtspOut, which is closely derived from FindUdpTcpOut, + except that the alias port (from FindNewPortGroup) is provided + as input. + See HISTORY file for additional revisions. - $OpenBSD: alias_db.c,v 1.12 2000/07/03 09:57:14 brian Exp $ + $OpenBSD: alias_db.c,v 1.13 2000/08/13 22:05:47 brian Exp $ */ @@ -500,6 +510,9 @@ Link creation and deletion: Link search: FindLinkOut() - find link for outgoing packets FindLinkIn() - find link for incoming packets + +Port search: + FindNewPortGroup() - find an available group of ports */ /* Local prototypes */ @@ -531,11 +544,14 @@ FindLinkIn(struct in_addr, struct in_addr, u_short, u_short, int, int); #define ALIAS_PORT_BASE 0x08000 #define ALIAS_PORT_MASK 0x07fff +#define ALIAS_PORT_MASK_EVEN 0x07ffe #define GET_NEW_PORT_MAX_ATTEMPTS 20 #define GET_ALIAS_PORT -1 #define GET_ALIAS_ID GET_ALIAS_PORT +#define FIND_EVEN_ALIAS_BASE 1 + /* GetNewPort() allocates port numbers. Note that if a port number is already in use, that does not mean that it cannot be used by another link concurrently. This is because GetNewPort() looks for @@ -704,6 +720,102 @@ GetSocket(u_short port_net, int *sockfd, int link_type) } +/* FindNewPortGroup() returns a base port number for an available + range of contiguous port numbers. Note that if a port number + is already in use, that does not mean that it cannot be used by + another link concurrently. This is because FindNewPortGroup() + looks for unused triplets: (dest addr, dest port, alias port). */ + +int +FindNewPortGroup(struct in_addr dst_addr, + struct in_addr alias_addr, + u_short src_port, + u_short dst_port, + u_short port_count, + u_char proto, + u_char align) +{ + int i, j; + int max_trials; + u_short port_sys; + int link_type; + + /* + * Get link_type from protocol + */ + + switch (proto) + { + case IPPROTO_UDP: + link_type = LINK_UDP; + break; + case IPPROTO_TCP: + link_type = LINK_TCP; + break; + default: + return (0); + break; + } + + /* + * The aliasing port is automatically selected + * by one of two methods below: + */ + max_trials = GET_NEW_PORT_MAX_ATTEMPTS; + + if (packetAliasMode & PKT_ALIAS_SAME_PORTS) { + /* + * When the ALIAS_SAME_PORTS option is + * chosen, the first try will be the + * actual source port. If this is already + * in use, the remainder of the trials + * will be random. + */ + port_sys = ntohs(src_port); + + } else { + + /* First trial and all subsequent are random. */ + if (align == FIND_EVEN_ALIAS_BASE) + port_sys = random() & ALIAS_PORT_MASK_EVEN; + else + port_sys = random() & ALIAS_PORT_MASK; + + port_sys += ALIAS_PORT_BASE; + } + +/* Port number search */ + for (i = 0; i < max_trials; i++) { + + struct alias_link *search_result; + + for (j = 0; j < port_count; j++) + if (0 != (search_result = FindLinkIn(dst_addr, alias_addr, + dst_port, htons(port_sys + j), + link_type, 0))) + break; + + /* Found a good range, return base */ + if (j == port_count) + return (htons(port_sys)); + + /* Find a new base to try */ + if (align == FIND_EVEN_ALIAS_BASE) + port_sys = random() & ALIAS_PORT_MASK_EVEN; + else + port_sys = random() & ALIAS_PORT_MASK; + + port_sys += ALIAS_PORT_BASE; + } + +#ifdef DEBUG + fprintf(stderr, "PacketAlias/FindNewPortGroup(): "); + fprintf(stderr, "could not find free port(s)\n"); +#endif + + return(0); +} + static void CleanupAliasData(void) { @@ -1600,6 +1712,107 @@ FindPptpOut(struct in_addr src_addr, } +struct alias_link * +QueryUdpTcpIn(struct in_addr dst_addr, + struct in_addr alias_addr, + u_short dst_port, + u_short alias_port, + u_char proto) +{ + int link_type; + struct alias_link *link; + + switch (proto) + { + case IPPROTO_UDP: + link_type = LINK_UDP; + break; + case IPPROTO_TCP: + link_type = LINK_TCP; + break; + default: + return NULL; + break; + } + + link = FindLinkIn(dst_addr, alias_addr, + dst_port, alias_port, + link_type, 0); + + return(link); +} + + +struct alias_link * +QueryUdpTcpOut(struct in_addr src_addr, + struct in_addr dst_addr, + u_short src_port, + u_short dst_port, + u_char proto) +{ + int link_type; + struct alias_link *link; + + switch (proto) + { + case IPPROTO_UDP: + link_type = LINK_UDP; + break; + case IPPROTO_TCP: + link_type = LINK_TCP; + break; + default: + return NULL; + break; + } + + link = FindLinkOut(src_addr, dst_addr, + src_port, dst_port, + link_type, 0); + + return(link); +} + + +struct alias_link * +FindRtspOut(struct in_addr src_addr, + struct in_addr dst_addr, + u_short src_port, + u_short alias_port, + u_char proto) +{ + int link_type; + struct alias_link *link; + + switch (proto) + { + case IPPROTO_UDP: + link_type = LINK_UDP; + break; + case IPPROTO_TCP: + link_type = LINK_TCP; + break; + default: + return NULL; + break; + } + + link = FindLinkOut(src_addr, dst_addr, src_port, 0, link_type, 1); + + if (link == NULL) + { + struct in_addr alias_addr; + + alias_addr = FindAliasAddress(src_addr); + link = AddLink(src_addr, dst_addr, alias_addr, + src_port, 0, alias_port, + link_type); + } + + return(link); +} + + struct in_addr FindOriginalAddress(struct in_addr alias_addr) { diff --git a/usr.sbin/ppp/ppp/alias_local.h b/usr.sbin/ppp/ppp/alias_local.h index 384e7d51c31..9d314cfb376 100644 --- a/usr.sbin/ppp/ppp/alias_local.h +++ b/usr.sbin/ppp/ppp/alias_local.h @@ -14,7 +14,7 @@ <updated several times by original author and Eivind Eklund> - $OpenBSD: alias_local.h,v 1.8 2000/06/23 09:47:05 brian Exp $ + $OpenBSD: alias_local.h,v 1.9 2000/08/13 22:05:47 brian Exp $ */ #ifndef ALIAS_LOCAL_H #define ALIAS_LOCAL_H @@ -113,6 +113,15 @@ FindPptpIn(struct in_addr, struct in_addr, u_short); struct alias_link * FindPptpOut(struct in_addr, struct in_addr, u_short); +struct alias_link * +QueryUdpTcpIn (struct in_addr, struct in_addr, u_short, u_short, u_char); + +struct alias_link * +QueryUdpTcpOut(struct in_addr, struct in_addr, u_short, u_short, u_char); + +struct alias_link * +FindRtspOut(struct in_addr, struct in_addr, u_short, u_short, u_char); + struct in_addr FindOriginalAddress(struct in_addr); @@ -120,6 +129,8 @@ struct in_addr FindAliasAddress(struct in_addr); /* External data access/modification */ +int FindNewPortGroup(struct in_addr, struct in_addr, + u_short, u_short, u_short, u_char, u_char); void GetFragmentAddr(struct alias_link *, struct in_addr *); void SetFragmentAddr(struct alias_link *, struct in_addr); void GetFragmentPtr(struct alias_link *, char **); @@ -165,6 +176,9 @@ void AliasHandleFtpOut(struct ip *, struct alias_link *, int); /* IRC routines */ void AliasHandleIrcOut(struct ip *, struct alias_link *, int); +/* RTSP routines */ +void AliasHandleRtspOut(struct ip *, struct alias_link *, int); + /* PPTP routines */ int PptpGetCallID(struct ip *, u_short *); void PptpSetCallID(struct ip *, u_short); diff --git a/usr.sbin/ppp/ppp/alias_pptp.c b/usr.sbin/ppp/ppp/alias_pptp.c index b1ce750e327..fe63d895891 100644 --- a/usr.sbin/ppp/ppp/alias_pptp.c +++ b/usr.sbin/ppp/ppp/alias_pptp.c @@ -35,7 +35,7 @@ * * Author: Erik Salander <erik@whistle.com> * - * $OpenBSD: alias_pptp.c,v 1.1 2000/06/23 09:47:05 brian Exp $ + * $OpenBSD: alias_pptp.c,v 1.2 2000/08/13 22:05:47 brian Exp $ */ /* @@ -45,8 +45,8 @@ "de-aliasing" of incoming packets, this is different than any other TCP applications that are currently (ie. FTP, IRC and RTSP) aliased. - For Call IDs encountered for the first time, a GRE alias link is created. - The GRE alias link uses the Call ID in place of the original port number. + For Call IDs encountered for the first time, a PPTP alias link is created. + The PPTP alias link uses the Call ID in place of the original port number. An alias Call ID is created. For this routine to work, the PPTP control messages must fit entirely @@ -114,7 +114,7 @@ enum { PPTP_StopCtrlConnRequest = 3, PPTP_StopCtrlConnReply = 4, PPTP_EchoRequest = 5, - PPTP_statoReply = 6, + PPTP_EchoReply = 6, PPTP_OutCallRequest = 7, PPTP_OutCallReply = 8, PPTP_InCallRequest = 9, @@ -172,7 +172,7 @@ void AliasHandlePptpOut(struct ip *pip, /* IP packet to examine/patch */ struct alias_link *link) /* The PPTP control link */ { - struct alias_link *gre_link; + struct alias_link *pptp_link; PptpCallId cptr; u_int16_t ctl_type; /* control message type */ struct tcphdr *tc; @@ -182,22 +182,32 @@ AliasHandlePptpOut(struct ip *pip, /* IP packet to examine/patch */ return; /* Modify certain PPTP messages */ - if ((ctl_type >= PPTP_OutCallRequest) && - (ctl_type <= PPTP_CallDiscNotify)) { + switch (ctl_type) { + case PPTP_OutCallRequest: + case PPTP_OutCallReply: + case PPTP_InCallRequest: + case PPTP_InCallReply: + case PPTP_CallClearRequest: + case PPTP_CallDiscNotify: - /* Establish GRE link for address and Call ID found in PPTP Control Msg */ - gre_link = FindPptpOut(GetOriginalAddress(link), GetDestAddress(link), - cptr->cid1); + /* Establish PPTP link for address and Call ID found in PPTP Control Msg */ + pptp_link = FindPptpOut(GetOriginalAddress(link), GetDestAddress(link), + cptr->cid1); + + if (pptp_link != NULL) { + int accumulate = cptr->cid1; - if (gre_link != NULL) { /* alias the Call Id */ - cptr->cid1 = GetAliasPort(gre_link); + cptr->cid1 = GetAliasPort(pptp_link); /* Compute TCP checksum for revised packet */ tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - tc->th_sum = 0; - tc->th_sum = TcpChecksum(pip); + accumulate -= cptr->cid1; + ADJUST_CHECKSUM(accumulate, tc->th_sum); } + break; + default: + return; } } @@ -205,7 +215,7 @@ void AliasHandlePptpIn(struct ip *pip, /* IP packet to examine/patch */ struct alias_link *link) /* The PPTP control link */ { - struct alias_link *gre_link; + struct alias_link *pptp_link; PptpCallId cptr; u_int16_t *pcall_id; u_int16_t ctl_type; /* control message type */ @@ -229,21 +239,22 @@ AliasHandlePptpIn(struct ip *pip, /* IP packet to examine/patch */ break; default: return; - break; } - /* Find GRE link for address and Call ID found in PPTP Control Msg */ - gre_link = FindPptpIn(GetDestAddress(link), GetAliasAddress(link), - *pcall_id); + /* Find PPTP link for address and Call ID found in PPTP Control Msg */ + pptp_link = FindPptpIn(GetDestAddress(link), GetAliasAddress(link), + *pcall_id); + + if (pptp_link != NULL) { + int accumulate = *pcall_id; - if (gre_link != NULL) { /* alias the Call Id */ - *pcall_id = GetOriginalPort(gre_link); + *pcall_id = GetOriginalPort(pptp_link); /* Compute TCP checksum for modified packet */ tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - tc->th_sum = 0; - tc->th_sum = TcpChecksum(pip); + accumulate -= *pcall_id; + ADJUST_CHECKSUM(accumulate, tc->th_sum); } } diff --git a/usr.sbin/ppp/ppp/radlib.c b/usr.sbin/ppp/ppp/radlib.c index 33ad64c0b0e..74620a652c1 100644 --- a/usr.sbin/ppp/ppp/radlib.c +++ b/usr.sbin/ppp/ppp/radlib.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: radlib.c,v 1.2 1999/05/08 11:06:39 brian Exp $ + * $OpenBSD: radlib.c,v 1.3 2000/08/13 22:05:47 brian Exp $ */ #include <sys/types.h> @@ -49,6 +49,7 @@ static void clear_password(struct rad_handle *); static void generr(struct rad_handle *, const char *, ...); static void insert_scrambled_password(struct rad_handle *, int); +static void insert_request_authenticator(struct rad_handle *, int); static int is_valid_response(struct rad_handle *, int, const struct sockaddr_in *); static int put_password_attr(struct rad_handle *, int, @@ -111,6 +112,23 @@ insert_scrambled_password(struct rad_handle *h, int srv) } } +static void +insert_request_authenticator(struct rad_handle *h, int srv) +{ + MD5_CTX ctx; + const struct rad_server *srvp; + + srvp = &h->servers[srv]; + + /* Create the request authenticator */ + MD5Init(&ctx); + MD5Update(&ctx, &h->request[POS_CODE], POS_AUTH - POS_CODE); + MD5Update(&ctx, memset(&h->request[POS_AUTH], 0, LEN_AUTH), LEN_AUTH); + MD5Update(&ctx, &h->request[POS_ATTRS], h->req_len - POS_ATTRS); + MD5Update(&ctx, srvp->secret, strlen(srvp->secret)); + MD5Final(&h->request[POS_AUTH], &ctx); +} + /* * Return true if the current response is valid for a request to the * specified server. @@ -230,9 +248,14 @@ rad_add_server(struct rad_handle *h, const char *host, int port, else { struct servent *sent; - srvp->addr.sin_port = - (sent = getservbyname("radius", "udp")) != NULL ? - sent->s_port : htons(RADIUS_PORT); + if (h->type == RADIUS_AUTH) + srvp->addr.sin_port = + (sent = getservbyname("radius", "udp")) != NULL ? + sent->s_port : htons(RADIUS_PORT); + else + srvp->addr.sin_port = + (sent = getservbyname("radacct", "udp")) != NULL ? + sent->s_port : htons(RADACCT_PORT); } if ((srvp->secret = strdup(secret)) == NULL) { generr(h, "Out of memory"); @@ -279,18 +302,21 @@ rad_config(struct rad_handle *h, const char *path) linenum = 0; while (fgets(buf, sizeof buf, fp) != NULL) { int len; - char *fields[4]; + char *fields[5]; int nfields; char msg[ERRSIZE]; + char *type; char *host; char *port_str; char *secret; char *timeout_str; char *maxtries_str; char *end; + char *wanttype; unsigned long timeout; unsigned long maxtries; int port; + int i; linenum++; len = strlen(buf); @@ -308,7 +334,7 @@ rad_config(struct rad_handle *h, const char *path) buf[len - 1] = '\0'; /* Extract the fields from the line. */ - nfields = split(buf, fields, 4, msg, sizeof msg); + nfields = split(buf, fields, 5, msg, sizeof msg); if (nfields == -1) { generr(h, "%s:%d: %s", path, linenum, msg); retval = -1; @@ -316,16 +342,41 @@ rad_config(struct rad_handle *h, const char *path) } if (nfields == 0) continue; - if (nfields < 2) { + /* + * The first field should contain "auth" or "acct" for + * authentication or accounting, respectively. But older + * versions of the file didn't have that field. Default + * it to "auth" for backward compatibility. + */ + if (strcmp(fields[0], "auth") != 0 && + strcmp(fields[0], "acct") != 0) { + if (nfields >= 5) { + generr(h, "%s:%d: invalid service type", path, + linenum); + retval = -1; + break; + } + nfields++; + for (i = nfields; --i > 0; ) + fields[i] = fields[i - 1]; + fields[0] = "auth"; + } + if (nfields < 3) { generr(h, "%s:%d: missing shared secret", path, linenum); retval = -1; break; } - host = fields[0]; - secret = fields[1]; - timeout_str = fields[2]; - maxtries_str = fields[3]; + type = fields[0]; + host = fields[1]; + secret = fields[2]; + timeout_str = fields[3]; + maxtries_str = fields[4]; + + /* Ignore the line if it is for the wrong service type. */ + wanttype = h->type == RADIUS_AUTH ? "auth" : "acct"; + if (strcmp(type, wanttype) != 0) + continue; /* Parse and validate the fields. */ host = strtok(host, ":"); @@ -422,9 +473,13 @@ rad_continue_send_request(struct rad_handle *h, int selected, int *fd, if (++h->srv >= h->num_servers) h->srv = 0; - /* Insert the scrambled password into the request */ - if (h->pass_pos != 0) - insert_scrambled_password(h, h->srv); + if (h->request[POS_CODE] == RAD_ACCOUNTING_REQUEST) + /* Insert the request authenticator into the request */ + insert_request_authenticator(h, h->srv); + else + /* Insert the scrambled password into the request */ + if (h->pass_pos != 0) + insert_scrambled_password(h, h->srv); /* Send the request */ n = sendto(h->fd, h->request, h->req_len, 0, @@ -553,14 +608,22 @@ rad_init_send_request(struct rad_handle *h, int *fd, struct timeval *tv) } } - /* Make sure the user gave us a password */ - if (h->pass_pos == 0 && !h->chap_pass) { - generr(h, "No User or Chap Password attributes given"); - return -1; - } - if (h->pass_pos != 0 && h->chap_pass) { - generr(h, "Both User and Chap Password attributes given"); - return -1; + if (h->request[POS_CODE] == RAD_ACCOUNTING_REQUEST) { + /* Make sure no password given */ + if (h->pass_pos || h->chap_pass) { + generr(h, "User or Chap Password in accounting request"); + return -1; + } + } else { + /* Make sure the user gave us a password */ + if (h->pass_pos == 0 && !h->chap_pass) { + generr(h, "No User or Chap Password attributes given"); + return -1; + } + if (h->pass_pos != 0 && h->chap_pass) { + generr(h, "Both User and Chap Password attributes given"); + return -1; + } } /* Fill in the length field in the message */ @@ -592,7 +655,7 @@ rad_init_send_request(struct rad_handle *h, int *fd, struct timeval *tv) * In that case, it returns NULL. */ struct rad_handle * -rad_open(void) +rad_auth_open(void) { struct rad_handle *h; @@ -607,10 +670,28 @@ rad_open(void) h->pass_len = 0; h->pass_pos = 0; h->chap_pass = 0; + h->type = RADIUS_AUTH; } return h; } +struct rad_handle * +rad_acct_open(void) +{ + struct rad_handle *h; + + h = rad_open(); + if (h != NULL) + h->type = RADIUS_ACCT; + return h; +} + +struct rad_handle * +rad_open(void) +{ + return rad_auth_open(); +} + int rad_put_addr(struct rad_handle *h, int type, struct in_addr addr) { diff --git a/usr.sbin/ppp/ppp/radlib.h b/usr.sbin/ppp/ppp/radlib.h index fd36e1a3644..cb5bb8d7565 100644 --- a/usr.sbin/ppp/ppp/radlib.h +++ b/usr.sbin/ppp/ppp/radlib.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: radlib.h,v 1.1 1999/02/06 03:22:45 brian Exp $ + * $OpenBSD: radlib.h,v 1.2 2000/08/13 22:05:47 brian Exp $ */ #ifndef _RADLIB_H_ @@ -36,6 +36,8 @@ #define RAD_ACCESS_REQUEST 1 #define RAD_ACCESS_ACCEPT 2 #define RAD_ACCESS_REJECT 3 +#define RAD_ACCOUNTING_REQUEST 4 +#define RAD_ACCOUNTING_RESPONSE 5 #define RAD_ACCESS_CHALLENGE 11 /* Attribute types and values */ @@ -66,6 +68,9 @@ #define RAD_FILTER_ID 11 /* String */ #define RAD_FRAMED_MTU 12 /* Integer */ #define RAD_FRAMED_COMPRESSION 13 /* Integer */ + #define RAD_COMP_NONE 0 + #define RAD_COMP_VJ 1 + #define RAD_COMP_IPXHDR 2 #define RAD_LOGIN_IP_HOST 14 /* IP address */ #define RAD_LOGIN_SERVICE 15 /* Integer */ #define RAD_LOGIN_TCP_PORT 16 /* Integer */ @@ -95,15 +100,63 @@ /* reserved for accounting 40-59 */ #define RAD_CHAP_CHALLENGE 60 /* String */ #define RAD_NAS_PORT_TYPE 61 /* Integer */ + #define RAD_ASYNC 0 + #define RAD_SYNC 1 + #define RAD_ISDN_SYNC 2 + #define RAD_ISDN_ASYNC_V120 3 + #define RAD_ISDN_ASYNC_V110 4 + #define RAD_VIRTUAL 5 #define RAD_PORT_LIMIT 62 /* Integer */ #define RAD_LOGIN_LAT_PORT 63 /* Integer */ +#define RAD_CONNECT_INFO 77 /* String */ + +/* Accounting attribute types and values */ +#define RAD_ACCT_STATUS_TYPE 40 /* Integer */ + #define RAD_START 1 + #define RAD_STOP 2 + #define RAD_ACCOUNTING_ON 7 + #define RAD_ACCOUNTING_OFF 8 +#define RAD_ACCT_DELAY_TIME 41 /* Integer */ +#define RAD_ACCT_INPUT_OCTETS 42 /* Integer */ +#define RAD_ACCT_OUTPUT_OCTETS 43 /* Integer */ +#define RAD_ACCT_SESSION_ID 44 /* String */ +#define RAD_ACCT_AUTHENTIC 45 /* Integer */ + #define RAD_AUTH_RADIUS 1 + #define RAD_AUTH_LOCAL 2 + #define RAD_AUTH_REMOTE 3 +#define RAD_ACCT_SESSION_TIME 46 /* Integer */ +#define RAD_ACCT_INPUT_PACKETS 47 /* Integer */ +#define RAD_ACCT_OUTPUT_PACKETS 48 /* Integer */ +#define RAD_ACCT_TERMINATE_CAUSE 49 /* Integer */ + #define RAD_TERM_USER_REQUEST 1 + #define RAD_TERM_LOST_CARRIER 2 + #define RAD_TERM_LOST_SERVICE 3 + #define RAD_TERM_IDLE_TIMEOUT 4 + #define RAD_TERM_SESSION_TIMEOUT 5 + #define RAD_TERM_ADMIN_RESET 6 + #define RAD_TERM_ADMIN_REBOOT 7 + #define RAD_TERM_PORT_ERROR 8 + #define RAD_TERM_NAS_ERROR 9 + #define RAD_TERM_NAS_REQUEST 10 + #define RAD_TERM_NAS_REBOOT 11 + #define RAD_TERM_PORT_UNNEEDED 12 + #define RAD_TERM_PORT_PREEMPTED 13 + #define RAD_TERM_PORT_SUSPENDED 14 + #define RAD_TERM_SERVICE_UNAVAILABLE 15 + #define RAD_TERM_CALLBACK 16 + #define RAD_TERM_USER_ERROR 17 + #define RAD_TERM_HOST_REQUEST 18 +#define RAD_ACCT_MULTI_SESSION_ID 50 /* String */ +#define RAD_ACCT_LINK_COUNT 51 /* Integer */ struct rad_handle; struct timeval; __BEGIN_DECLS +struct rad_handle *rad_acct_open(void); int rad_add_server(struct rad_handle *, const char *, int, const char *, int, int); +struct rad_handle *rad_auth_open(void); void rad_close(struct rad_handle *); int rad_config(struct rad_handle *, const char *); int rad_continue_send_request(struct rad_handle *, int, @@ -116,7 +169,7 @@ int rad_get_attr(struct rad_handle *, const void **, size_t *); int rad_init_send_request(struct rad_handle *, int *, struct timeval *); -struct rad_handle *rad_open(void); +struct rad_handle *rad_open(void); /* Deprecated, == rad_auth_open */ int rad_put_addr(struct rad_handle *, int, struct in_addr); int rad_put_attr(struct rad_handle *, int, const void *, size_t); diff --git a/usr.sbin/ppp/ppp/radlib_private.h b/usr.sbin/ppp/ppp/radlib_private.h index 4ccb6e443dc..dd8560684f6 100644 --- a/usr.sbin/ppp/ppp/radlib_private.h +++ b/usr.sbin/ppp/ppp/radlib_private.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: radlib_private.h,v 1.1 1999/02/06 03:22:45 brian Exp $ + * $OpenBSD: radlib_private.h,v 1.2 2000/08/13 22:05:48 brian Exp $ */ #ifndef RADLIB_PRIVATE_H @@ -34,10 +34,15 @@ #include "radlib.h" +/* Handle types */ +#define RADIUS_AUTH 0 /* RADIUS authentication, default */ +#define RADIUS_ACCT 1 /* RADIUS accounting */ + /* Defaults */ #define MAXTRIES 3 #define PATH_RADIUS_CONF "/etc/radius.conf" #define RADIUS_PORT 1812 +#define RADACCT_PORT 1813 #define TIMEOUT 3 /* In seconds */ /* Limits */ @@ -81,6 +86,7 @@ struct rad_handle { int total_tries; /* How many requests we'll send */ int try; /* How many requests we've sent */ int srv; /* Server number we did last */ + int type; /* Handle type */ }; #endif |