Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 718350 Details for
Bug 648217
Enhancement request: Add EAP-PEAP support for RADIUS plugin
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
EAP-{TLS|TTLS|PEAP} Patch for PPPd RADIUS Plugin including support of "Calling-Station-Id"
ppp-2.4.5-radius-eaptls-ttls-peap.patch (text/plain), 75.65 KB, created by
Michal Bruncko
on 2013-03-30 19:33:31 UTC
(
hide
)
Description:
EAP-{TLS|TTLS|PEAP} Patch for PPPd RADIUS Plugin including support of "Calling-Station-Id"
Filename:
MIME Type:
Creator:
Michal Bruncko
Created:
2013-03-30 19:33:31 UTC
Size:
75.65 KB
patch
obsolete
>diff -Nu ppp-2.4.5-orig/pppd/auth.c ppp-wegener-despace-stripnum/pppd/auth.c >--- ppp-2.4.5-orig/pppd/auth.c 2009-11-16 23:26:07.000000000 +0100 >+++ ppp-wegener-despace-stripnum/pppd/auth.c 2013-01-14 18:11:15.949533401 +0100 >@@ -183,6 +185,9 @@ > /* Hook for a plugin to get the CHAP password for authenticating us */ > int (*chap_passwd_hook) __P((char *user, char *passwd)) = NULL; > >+/* Hook for a plugin to authenticate a peer with EAP TLS */ >+int (*eaptls_auth_hook) __P((char *peerName, int peerNameLen, char *eapTLSContent, int *contentLen)); >+ > /* Hook for a plugin to say whether it is OK if the peer > refuses to authenticate. */ > int (*null_auth_hook) __P((struct wordlist **paddrs, >diff -Nu ppp-2.4.5-orig/pppd/eap.c ppp-wegener-despace-stripnum/pppd/eap.c >--- ppp-2.4.5-orig/pppd/eap.c 2009-11-16 23:26:07.000000000 +0100 >+++ ppp-wegener-despace-stripnum/pppd/eap.c 2007-12-03 08:59:21.000000000 +0100 >@@ -41,6 +41,9 @@ > * authenticator-driven protocol. > * > * Based on draft-ietf-pppext-eap-srp-03.txt. >+ * >+ * EAP TLS support by: >+ * michael.heiart@freenet.de > */ > > #define RCSID "$Id: eap.c,v 1.4 2004/11/09 22:39:25 paulus Exp $" >@@ -443,6 +447,14 @@ > return; > > case eapIdentify: >+ /* If we have an eaptls_auth_hook let remote peer and RADIUS server >+ negotiate how to authenticate (Exchange EAP messages). >+ Otherwise let pppd code handle the authentication */ >+ if(eaptls_auth_hook != NULL){ >+ esp->es_server.ea_state = eapTLSAuth; >+ break; >+ } >+ > #ifdef USE_SRP > /* Discard any previous session. */ > ts = (struct t_server *)esp->es_server.ea_session; >@@ -624,6 +636,14 @@ > } > break; > >+ case eapTLSAuth: >+ if (status != 0) { >+ esp->es_server.ea_state = eapBadAuth; >+ } else { >+ esp->es_server.ea_state = eapOpen; >+ } >+ break; >+ > default: > esp->es_server.ea_state = eapBadAuth; > break; >@@ -646,6 +666,14 @@ > int outlen; > int challen; > char *str; >+ int result; >+ char decapsulated_eaptls[2048]; >+ int eaptls_len; >+ >+ lenloc = NULL; >+ result = 0; >+ eaptls_len = 0; >+ > #ifdef USE_SRP > struct t_server *ts; > u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp; >@@ -681,13 +709,16 @@ > } > > outp = outpacket_buf; >- >+ > MAKEHEADER(outp, PPP_EAP); > >- PUTCHAR(EAP_REQUEST, outp); >- PUTCHAR(esp->es_server.ea_id, outp); >- lenloc = outp; >- INCPTR(2, outp); >+ /* no indenting if pppd is proxy for eap tls */ >+ if(esp->es_server.ea_state != eapTLSAuth){ >+ PUTCHAR(EAP_REQUEST, outp); >+ PUTCHAR(esp->es_server.ea_id, outp); >+ lenloc = outp; >+ INCPTR(2, outp); >+ } > > switch (esp->es_server.ea_state) { > case eapIdentify: >@@ -698,6 +729,39 @@ > INCPTR(challen, outp); > break; > >+ case eapTLSAuth: >+ if(eaptls_auth_hook != NULL){ >+ result = eaptls_auth_hook(esp->es_server.ea_peer, >+ esp->es_server.ea_peerlen, >+ decapsulated_eaptls, >+ &eaptls_len); >+ >+ /* Decapsulate the attributes and move on >+ or inform the client that access is granted or >+ denied. If an error occors on the RADIUS Server side >+ (code 4) the client will only see that the access was denied */ >+ if((result != 0) || (decapsulated_eaptls[0] == 2) || (decapsulated_eaptls[0] == 4)) >+ { >+ eap_send_failure(esp); >+ return; >+ }else{ >+ str = decapsulated_eaptls; >+ challen = eaptls_len; >+ BCOPY(str, outp, challen); >+ INCPTR(challen, outp); >+ >+ if(decapsulated_eaptls[0] == 3){ >+ eap_send_success(esp); >+ } >+ } >+ }else{ >+ error("EAP TLS: No eaptls_auth_hook found!"); >+ eap_send_failure(esp); >+ return; >+ } >+ >+ break; >+ > case eapMD5Chall: > PUTCHAR(EAPT_MD5CHAP, outp); > /* >@@ -854,7 +918,11 @@ > } > > outlen = (outp - outpacket_buf) - PPP_HDRLEN; >- PUTSHORT(outlen, lenloc); >+ /* eapTlsContent already contains its length >+ for other authentication methods the length must be set */ >+ if(esp->es_server.ea_state != eapTLSAuth){ >+ PUTSHORT(outlen, lenloc); >+ } > > output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN); > >@@ -1754,6 +1822,12 @@ > len--; > > switch (typenum) { >+ case EAPT_TLS: >+ case EAPT_TTLS: >+ /* use a Radius Server to authenticate this peer with EAP TLS */ >+ esp->es_server.ea_state = eapTLSAuth; >+ break; >+ > case EAPT_IDENTITY: > if (esp->es_server.ea_state != eapIdentify) { > dbglog("EAP discarding unwanted Identify \"%.q\"", len, >@@ -1761,6 +1835,7 @@ > break; > } > info("EAP: unauthenticated peer name \"%.*q\"", len, inp); >+ > if (esp->es_server.ea_peer != NULL && > esp->es_server.ea_peer != remote_name) > free(esp->es_server.ea_peer); >@@ -1797,7 +1872,16 @@ > } > > switch (vallen) { >- case EAPT_SRP: >+ case EAPT_TLS: >+ esp->es_server.ea_state = eapTLSAuth; >+ break; >+ >+ case EAPT_SRP: /* now EAP-SRP is suupported by radius too */ >+ if(eaptls_auth_hook != NULL) { >+ esp->es_server.ea_state = eapTLSAuth; >+ break; >+ } >+ > /* Run through SRP validator selection again. */ > esp->es_server.ea_state = eapIdentify; > eap_figure_next_state(esp, 0); >@@ -1890,6 +1974,11 @@ > > #ifdef USE_SRP > case EAPT_SRP: >+ if(eaptls_auth_hook != NULL) { /* now radius supports SRP too */ >+ esp->es_server.ea_state = eapTLSAuth; >+ break; >+ } >+ > if (len < 1) { > error("EAP: empty SRP Response"); > eap_figure_next_state(esp, 1); >diff -Nu ppp-2.4.5-orig/pppd/eap.h ppp-wegener-despace-stripnum/pppd/eap.h >--- ppp-2.4.5-orig/pppd/eap.h 2009-11-16 23:26:07.000000000 +0100 >+++ ppp-wegener-despace-stripnum/pppd/eap.h 2007-04-26 11:33:12.000000000 +0200 >@@ -59,6 +59,7 @@ > #define EAPT_NOKIACARD 18 /* Nokia IP smart card */ > #define EAPT_SRP 19 /* Secure Remote Password */ > /* 20 is deprecated */ >+#define EAPT_TTLS 21 /* Tunnelles TLS */ > > /* EAP SRP-SHA1 Subtypes */ > #define EAPSRP_CHALLENGE 1 /* Request 1 - Challenge */ >@@ -88,6 +89,7 @@ > eapSRP2, /* Sent EAP SRP-SHA1 Subtype 2 */ > eapSRP3, /* Sent EAP SRP-SHA1 Subtype 3 */ > eapMD5Chall, /* Sent MD5-Challenge */ >+ eapTLSAuth, /* Work as proxy for EAP TLS */ > eapOpen, /* Completed authentication */ > eapSRP4, /* Sent EAP SRP-SHA1 Subtype 4 */ > eapBadAuth /* Failed authentication */ >@@ -95,7 +97,7 @@ > > #define EAP_STATES \ > "Initial", "Pending", "Closed", "Listen", "Identify", \ >- "SRP1", "SRP2", "SRP3", "MD5Chall", "Open", "SRP4", "BadAuth" >+ "SRP1", "SRP2", "SRP3", "MD5Chall", "TLSChall", "Open", "SRP4", "BadAuth" > > #define eap_client_active(esp) ((esp)->es_client.ea_state == eapListen) > #define eap_server_active(esp) \ >diff -Nu ppp-2.4.5-orig/pppd/pppd.h ppp-wegener-despace-stripnum/pppd/pppd.h >--- ppp-2.4.5-orig/pppd/pppd.h 2009-11-16 23:26:07.000000000 +0100 >+++ ppp-wegener-despace-stripnum/pppd/pppd.h 2005-04-12 18:55:55.000000000 +0200 >@@ -80,6 +80,7 @@ > #define MAXARGS 1 /* max # args to a command */ > #define MAXNAMELEN 256 /* max length of hostname or name for auth */ > #define MAXSECRETLEN 256 /* max length of password or secret */ >+#define MAXEAPTLSLEN 2048 /* max length of eap tls content */ > > /* > * Option descriptor structure. >@@ -717,6 +715,8 @@ > extern int (*chap_passwd_hook) __P((char *user, char *passwd)); > extern void (*multilink_join_hook) __P((void)); > >+extern int (*eaptls_auth_hook) __P((char *peerName, int peerNameLen, char *eapTLSContent, int *contentLen)); >+ > /* Let a plugin snoop sent and received packets. Useful for L2TP */ > extern void (*snoop_recv_hook) __P((unsigned char *p, int len)); > extern void (*snoop_send_hook) __P((unsigned char *p, int len)); > >diff -rNu ppp-2.4.5-orig/pppd/plugins/radius/etc/dictionary ppp-wegener-despace-stripnum/pppd/plugins/radius/etc/dictionary >--- ppp-2.4.5-orig/pppd/plugins/radius/etc/dictionary 2009-11-16 23:26:07.000000000 +0100 >+++ ppp-wegener-despace-stripnum/pppd/plugins/radius/etc/dictionary 2005-04-06 14:23:07.000000000 +0200 >@@ -87,6 +87,9 @@ > ATTRIBUTE Port-Limit 62 integer > ATTRIBUTE Connect-Info 77 string > >+ATTRIBUTE EAP-Message 79 string >+ATTRIBUTE EAP-Message-Authenticator 80 string >+ > # RFC 2869 > ATTRIBUTE Acct-Interim-Interval 85 integer > >@@ -251,3 +254,5 @@ > VALUE Octets-Direction MaxSession 4 > > INCLUDE /etc/radiusclient/dictionary.microsoft >+INCLUDE /etc/radiusclient/dictionary.cisco >+INCLUDE /etc/radiusclient/dictionary.siemens >diff -rNu ppp-2.4.5-orig/pppd/plugins/radius/etc/dictionary.cisco ppp-wegener-despace-stripnum/pppd/plugins/radius/etc/dictionary.cisco >--- ppp-2.4.5-orig/pppd/plugins/radius/etc/dictionary.cisco 1970-01-01 01:00:00.000000000 +0100 >+++ ppp-wegener-despace-stripnum/pppd/plugins/radius/etc/dictionary.cisco 2005-04-06 14:23:07.000000000 +0200 >@@ -0,0 +1,13 @@ >+# >+# Siemens dictionary for X.509 certificate attributes >+# >+# >+# Version: 1.00 18-Mar-2005 Michael Heiart >+# >+ >+VENDOR Cisco 9 >+ >+BEGIN-VENDOR Cisco >+# we need this to emulate a cisco ap with our pppd >+ATTRIBUTE Cisco-AVPair 1 string Cisco >+END-VENDOR Cisco >diff -rNu ppp-2.4.5-orig/pppd/plugins/radius/etc/dictionary.siemens ppp-wegener-despace-stripnum/pppd/plugins/radius/etc/dictionary.siemens >--- ppp-2.4.5-orig/pppd/plugins/radius/etc/dictionary.siemens 1970-01-01 01:00:00.000000000 +0100 >+++ ppp-wegener-despace-stripnum/pppd/plugins/radius/etc/dictionary.siemens 2005-04-06 14:23:07.000000000 +0200 >@@ -0,0 +1,34 @@ >+# >+# Siemens dictionary for X.509 certificate attributes >+# >+# >+# Version: 1.00 04-Apr-2005 Michael Joosten >+# >+ >+VENDOR Siemens 4329 >+ >+BEGIN-VENDOR Siemens >+# general X509 subject/issuer attributes >+ >+ATTRIBUTE UserCert-CN 221 string Siemens >+ATTRIBUTE UserCert-SN 222 string Siemens >+ATTRIBUTE UserCert-GN 223 string Siemens >+ATTRIBUTE UserCert-O 224 string Siemens >+ATTRIBUTE UserCert-OU 225 string Siemens >+ATTRIBUTE UserCert-ST 226 string Siemens >+ATTRIBUTE UserCert-L 227 string Siemens >+ATTRIBUTE UserCert-Title 228 string Siemens >+ATTRIBUTE UserCert-Desc 229 string Siemens >+ATTRIBUTE UserCert-Name 230 string Siemens >+ATTRIBUTE UserCert-Initials 231 string Siemens >+ATTRIBUTE UserCert-Pseudonym 232 string Siemens >+ATTRIBUTE UserCert-Role 233 string Siemens >+ >+# some X509v3 extension attributes >+ATTRIBUTE UserCert-UPN 240 string Siemens >+ATTRIBUTE UserCert-URI 241 string Siemens >+ATTRIBUTE UserCert-DNS 242 string Siemens >+ATTRIBUTE UserCert-Email 243 string Siemens >+ATTRIBUTE UserCert-TCGID 244 string Siemens >+ >+END-VENDOR Siemens >diff -rNu ppp-2.4.5-orig/pppd/plugins/radius/Makefile.linux ppp-wegener-despace-stripnum/pppd/plugins/radius/Makefile.linux >--- ppp-2.4.5-orig/pppd/plugins/radius/Makefile.linux 2013-01-14 11:19:30.552418072 +0100 >+++ ppp-wegener-despace-stripnum/pppd/plugins/radius/Makefile.linux 2013-01-14 17:41:10.211411163 +0100 >@@ -21,6 +21,9 @@ > MPPE=y > # Uncomment the next lint to include support for traffic limiting > MAXOCTETS=y >+# Uncomment the next lint to include support EAP TLS >+EAPTLS=y >+ > > ifdef CHAPMS > CFLAGS += -DCHAPMS=1 >@@ -31,6 +34,10 @@ > ifdef MAXOCTETS > CFLAGS += -DMAXOCTETS=1 > endif >+ifdef EAPTLS >+CFLAGS += -DEAPTLS=1 >+endif >+ > > all: $(PLUGIN) > >diff -rNu ppp-2.4.5-orig/pppd/plugins/radius/radius.c ppp-wegener-despace-stripnum/pppd/plugins/radius/radius.c >--- ppp-2.4.5-orig/pppd/plugins/radius/radius.c 2013-01-14 17:51:22.891407936 +0100 >+++ ppp-wegener-despace-stripnum/pppd/plugins/radius/radius.c 2013-01-15 15:23:28.741407706 +0100 >@@ -19,6 +19,13 @@ > * MPPE support is by Ralf Hofmann, <ralf.hofmann@elvido.net>, with > * modification from Frank Cusack, <frank@google.com>. > * >+* EAP TLS support by: >+* Michael Heiart, <michael.heiart@freenet.de> and >+* Michael Joosten, <michael.joosten@c-lab.de> >+* >+* Sync pppd with new radiusclient lib by: >+* Dirk Nehring, <dnehring@marcant.net>* >+* > * This plugin may be distributed according to the terms of the GNU > * General Public License, version 2 or (at your option) any later version. > * >@@ -35,6 +42,7 @@ > #endif > #endif > #include "radiusclient.h" >+#include "eap.h" > #include "fsm.h" > #include "ipcp.h" > #include <syslog.h> >@@ -45,6 +53,13 @@ > #include <stdlib.h> > > #define BUF_LEN 1024 >+#include <sys/socket.h> >+#include <netinet/in.h> >+#include <arpa/inet.h> >+ >+#include <sys/types.h> >+#include <unistd.h> >+#include <sys/stat.h> > > #define MD5_HASH_SIZE 16 > >@@ -78,6 +93,13 @@ > unsigned char *response, > char *message, int message_space); > >+static int radius_eaptls(char *peername, >+ int peernameLen, >+ char *eapTLSContent, >+ int *contentLen); >+ >+static void radius_snoop_received(unsigned char *pppPacket, int len); >+ > static void radius_ip_up(void *opaque, int arg); > static void radius_ip_down(void *opaque, int arg); > static void make_username_realm(char *user); >@@ -122,6 +144,14 @@ > int class_len; > char class[MAXCLASSLEN]; > VALUE_PAIR *avp; /* Additional (user supplied) vp's to send to server */ >+ unsigned char *ppp_snoop_data; >+ int ppp_snoop_len; >+ int state_attr_len; >+ char state_attr[512]; >+ char radius_cert_UPN[256]; >+ char radius_cert_CN[256]; >+ char radius_cert_TCGID[256]; >+ char radius_acct_username[128]; > }; > > void (*radius_attributes_hook)(VALUE_PAIR *) = NULL; >@@ -136,6 +166,13 @@ > > char pppd_version[] = VERSION; > >+/* 0 = NO EAP-Message-Authenticator needed. 1 = Needed */ >+int eap_tls_flag = 0; >+ >+/* extracted data from RADIUS user certificate attributes >+ * (requires FreeRadius patch) >+ */ >+ > /********************************************************************** > * %FUNCTION: plugin_init > * %ARGUMENTS: >@@ -154,6 +191,15 @@ > chap_check_hook = radius_secret_check; > chap_verify_hook = radius_chap_verify; > >+#ifdef EAPTLS >+ info("Using EAP TLS."); >+ eaptls_auth_hook = radius_eaptls; >+#else >+ eaptls_auth_hook = NULL; >+#endif >+ >+ snoop_recv_hook = radius_snoop_received; >+ > ip_choose_hook = radius_choose_ip; > allowed_address_hook = radius_allowed_address; > >@@ -167,6 +213,14 @@ > > add_options(Options); > >+ eap_tls_flag = 0; >+ >+ rstate.radius_cert_UPN[0]='\0'; >+ rstate.radius_cert_CN[0]='\0'; >+ rstate.radius_cert_TCGID[0]='\0'; >+ >+ rstate.state_attr_len = 0; >+ > info("RADIUS plugin initialized."); > } > >@@ -242,6 +296,7 @@ > radius_pap_auth(char *user, > char *passwd, > char **msgp, >+ > struct wordlist **paddrs, > struct wordlist **popts) > { >@@ -309,7 +364,13 @@ > rc_avpair_free(received); > rc_avpair_free(send); > >- return (result == OK_RC) ? 1 : 0; >+ if(result == OK_RC){ >+ >+ return 2; /* this means UPAP_AUTHACK in auth.c / user authenticated successfully by RADIUS server */ >+ >+ } else { >+ return 3; /* this means UPAP_AUTHNAK in auth.c / user rejected by RADIUS server */ >+ } > } > > /********************************************************************** >@@ -487,6 +548,7 @@ > > rc_avpair_free(received); > rc_avpair_free (send); >+ > return (result == OK_RC); > } > >@@ -543,6 +605,12 @@ > int mppe_enc_policy = 0; > int mppe_enc_types = 0; > #endif >+ char name[128]; >+ char value [128]; >+ >+ /* CISCO proprietary attrs for DNS and WINS */ >+ char *cisco_ip_str, *cisco_end_ip_str; >+ unsigned long int ip = 0; > > /* Send RADIUS attributes to anyone else who might be interested */ > if (radius_attributes_hook) { >@@ -554,8 +622,20 @@ > * new IP address (RADIUS can define static IP for some users), > */ > >- while (vp) { >- if (vp->vendorcode == VENDOR_NONE) { >+ while(vp) >+ { >+ if (debug) >+ { >+ /* print returned attributes */ >+ if (rc_avpair_tostr(vp, name, sizeof(name), value, sizeof(value)) >= 0) >+ { >+ dbglog("Vendor '%d' Attr '%s', Code '%d' ==> Val '%s'\n", vp->vendorcode, >+ name, vp->attribute, value); >+ } >+ } >+ >+ if (vp->vendorcode == VENDOR_NONE) >+ { > switch (vp->attribute) { > case PW_SERVICE_TYPE: > /* check for service type */ >@@ -706,11 +706,68 @@ > memcpy(rstate.class, vp->strvalue, rstate.class_len); > } /* else too big for our buffer - ignore it */ > break; >+ >+ /* internal Radius server attribute */ >+ case PW_STATE: >+ /* preserve the RADIUS state between requests! */ >+ if (vp->lvalue <= sizeof(rstate.state_attr)) { >+ rstate.state_attr_len = vp->lvalue; >+ memcpy(rstate.state_attr, vp->strvalue, rstate.state_attr_len); >+ } >+ break; > } > >+ }else if(vp->vendorcode == VENDOR_CISCO) { >+ if (vp->attribute == PW_CISCO_AVPAIR) { >+ /* emulate what a CISCO AP would do (more or less) */ >+ if(strstr(vp->strvalue, "ip:dns-servers=") != NULL) { >+ cisco_ip_str = vp->strvalue + sizeof("ip:dns-servers=")-1; >+ >+ /* mult. entries separated by ' ' only */ >+ cisco_end_ip_str = strchr(cisco_ip_str, ' '); >+ if (cisco_end_ip_str == NULL) { >+ dbglog("Cisco DNS server attribute: %s", cisco_ip_str); >+ ip = inet_addr(cisco_ip_str); >+ ipcp_allowoptions[0].dnsaddr[0] = ip; >+ ipcp_allowoptions[0].dnsaddr[1] = ip; >+ } else { >+ /* we got a space, so extract two dotted IP addresses */ >+ *cisco_end_ip_str++ = '\0'; >+ dbglog("Cisco DNS1 server attribute: %s", cisco_ip_str); >+ ip = inet_addr(cisco_ip_str); >+ ipcp_allowoptions[0].dnsaddr[0] = ip; >+ dbglog("Cisco DNS2 server attribute: %s", cisco_end_ip_str); >+ ip = inet_addr(cisco_end_ip_str); >+ ipcp_allowoptions[0].dnsaddr[1] = ip; >+ } >+ } >+ >+ if(strstr(vp->strvalue, "ip:wins-servers=") != NULL){ >+ cisco_ip_str = vp->strvalue + sizeof("ip:wins-servers=")-1; >+ >+ /* mult. entries separated by ' ' only */ >+ cisco_end_ip_str = strchr(cisco_ip_str, ' '); >+ if (cisco_end_ip_str == NULL) { >+ dbglog("Cisco WINS server attribute: %s", cisco_ip_str); >+ ip = inet_addr(cisco_ip_str); >+ ipcp_allowoptions[0].winsaddr[0] = ip; >+ ipcp_allowoptions[0].winsaddr[1] = ip; >+ } else { >+ /* we got a space, so extract two dotted IP addresses */ >+ *cisco_end_ip_str++ = '\0'; >+ dbglog("Cisco WINS1 server attribute: %s", cisco_ip_str); >+ ip = inet_addr(cisco_ip_str); >+ ipcp_allowoptions[0].winsaddr[0] = ip; >+ dbglog("Cisco WINS2 server attribute: %s", cisco_end_ip_str); >+ ip = inet_addr(cisco_end_ip_str); >+ ipcp_allowoptions[0].winsaddr[1] = ip; >+ } >+ } >+ } >+ } /*End of vendor CISCO */ > > #ifdef CHAPMS >- } else if (vp->vendorcode == VENDOR_MICROSOFT) { >+ else if (vp->vendorcode == VENDOR_MICROSOFT) { > switch (vp->attribute) { > case PW_MS_CHAP2_SUCCESS: > if ((vp->lvalue != 43) || strncmp(vp->strvalue + 1, "S=", 2)) { >@@ -673,13 +811,23 @@ > break; > > #endif /* MPPE */ >-#if 0 >+ > case PW_MS_PRIMARY_DNS_SERVER: >+ ipcp_allowoptions[0].dnsaddr[0] = ntohl(vp->lvalue); >+ break; >+ > case PW_MS_SECONDARY_DNS_SERVER: >+ ipcp_allowoptions[0].dnsaddr[1] = ntohl(vp->lvalue); >+ break; >+ > case PW_MS_PRIMARY_NBNS_SERVER: >+ ipcp_allowoptions[0].winsaddr[0] = ntohl(vp->lvalue); >+ break; >+ > case PW_MS_SECONDARY_NBNS_SERVER: >+ ipcp_allowoptions[0].winsaddr[1] = ntohl(vp->lvalue); > break; >-#endif >+ > } > #endif /* CHAPMS */ > } >@@ -1029,7 +1177,7 @@ > case EXIT_CONNECT_TIME: > av_type = PW_ACCT_SESSION_TIMEOUT; > break; >- >+ > #ifdef MAXOCTETS > case EXIT_TRAFFIC_LIMIT: > av_type = PW_NAS_REQUEST; >@@ -1304,3 +1452,223 @@ > { > return rstate.user; > } >+ >+/********************************************************************** >+* %FUNCTION: radius_eaptls >+* Performs EAP TLS authentications with >+* a RADIUS Server. >+* %ARGUMENTS: >+* peername -- username(identity) of remote peer >+* peername_len -- length of username(identity) of remote peer >+* peername -- username(identity) of remote peer >+* eaptls_content -- the buffer to return the eap tls messages received from RADIUS server >+* content_len -- the length of the eap tls content received from the RADIUS server >+* %RETURNS: >+* 0 if it was possible to communcate with the RADIUS server; >+* 1 if problems occured during communication with RADIUS server >+***********************************************************************/ >+static int >+radius_eaptls(char *peername, int peername_len, char *eaptls_content, int *content_len) >+{ >+ VALUE_PAIR *send, *received, *avpairs; >+ int result; >+ static char radius_msg[BUF_LEN]; >+ int type = 0; >+ int contentSize = 0; >+ >+#ifdef MPPE >+ /* Need the RADIUS secret and Request Authenticator to decode MPPE */ >+ REQUEST_INFO request_info, *req_info = &request_info; >+#else >+ REQUEST_INFO *req_info = NULL; >+#endif >+ >+ memcpy(rstate.user, peername, peername_len); >+ rstate.user[peername_len] = 0; >+ >+ radius_msg[0] = 0; >+ >+ if (radius_init(radius_msg) < 0) { >+ return 0; >+ } >+ >+ if (radius_pre_auth_hook) { >+ radius_pre_auth_hook(rstate.user, >+ &rstate.authserver, >+ &rstate.acctserver); >+ } >+ >+ send = NULL; >+ received = NULL; >+ >+ /* Hack... the "port" is the ppp interface number. >+ * Should really be the tty */ >+ rstate.client_port = get_client_port(portnummap ? devnam : ifname); >+ >+ /* Add User-Name attribute */ >+ type = PW_USER_NAME; >+ rc_avpair_add(&send, type, rstate.user, strlen(rstate.user)+1, VENDOR_NONE); >+ >+ /* Add EAP Message attribute with previously received EAP packet from peer */ >+ /* Maximum length of an eap message is 255 (type + length + String) */ >+ /* Therefore a length of 253 = EAP_TLS_MAX_STRING_LEN is left for our chunk */ >+ type = PW_EAP_MESSAGE; >+ if (rstate.ppp_snoop_len-4 <= EAP_TLS_MAX_STRING_LEN) { >+ rc_avpair_add(&send, type, rstate.ppp_snoop_data+4, rstate.ppp_snoop_len-4, VENDOR_NONE); >+ } else { >+ /* write EAP frament in chunks of 253 bytes payload or the rest of payload left*/ >+ int written = 0; >+ int chunk = EAP_TLS_MAX_STRING_LEN; >+ while (written < rstate.ppp_snoop_len-4) { >+ rc_avpair_add(&send, type, rstate.ppp_snoop_data+4+written, chunk, VENDOR_NONE); >+ written += chunk; >+ if(rstate.ppp_snoop_len-4-written >= EAP_TLS_MAX_STRING_LEN){ >+ chunk = EAP_TLS_MAX_STRING_LEN; >+ }else{ >+ chunk = rstate.ppp_snoop_len-4-written; >+ } >+ } >+ } >+ >+ /* Add a state attribute >+ * The Radius server uses the state attribute to find the dataset >+ * belonging to an authentication process */ >+ if (rstate.state_attr_len > 0) { >+ type = PW_STATE; >+ rc_avpair_add(&send, type, rstate.state_attr, rstate.state_attr_len, VENDOR_NONE); >+ } >+ >+ /* Add user specified vp's */ >+ if (rstate.avp) >+ rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp)); >+ >+ /* Indicate that a Message Authenticator is necessary */ >+ eap_tls_flag = 1; >+ >+ if (rstate.authserver) { >+ result = rc_auth_using_server(rstate.authserver, >+ rstate.client_port, send, >+ &received, radius_msg, req_info); >+ } else { >+ result = rc_auth(rstate.client_port, send, &received, radius_msg, req_info); >+ } >+ >+ /* extract common attributes */ >+ if (result == OK_RC) { >+ if (radius_setparams(received, radius_msg, req_info, NULL, NULL, NULL, 0) < 0) { >+ result = ERROR_RC; >+ } >+ } >+ >+ /* Radius Client acts as proxy */ >+ /* decapsulate pure EAP that can be send to the peer */ >+ contentSize = 0; >+ >+ /* extract EAP/TLS specific attributes */ >+ avpairs = received; >+ for( ; received ; received = received->next) { >+ >+ /* X509 certificate specific attributes from FreeRadius */ >+ if (received->vendorcode == VENDOR_SIEMENS) { >+ switch(received->attribute){ >+ case PW_USERCERT_UPN: >+ strncpy(rstate.radius_cert_UPN, received->strvalue, sizeof(rstate.radius_cert_UPN)-1); >+ rstate.radius_cert_UPN[sizeof(rstate.radius_cert_UPN)-1] = '\0'; >+ break; >+ case PW_USERCERT_CN: >+ strncpy(rstate.radius_cert_CN, received->strvalue, sizeof(rstate.radius_cert_CN)-1); >+ rstate.radius_cert_CN[sizeof(rstate.radius_cert_CN)-1] = '\0'; >+ case PW_USERCERT_TCGID: >+ strncpy(rstate.radius_cert_TCGID, received->strvalue, sizeof(rstate.radius_cert_TCGID)-1); >+ rstate.radius_cert_TCGID[sizeof(rstate.radius_cert_TCGID)-1] = '\0'; >+ } >+ } >+ >+ if(received->attribute == PW_EAP_MESSAGE){ >+ /* does the Radius fragment still fit in to the EAP-TLS fragment buffer? */ >+ if (received->lvalue < EAP_TLS_MAX_BUFFER_LEN - contentSize){ >+ memcpy(&eaptls_content[contentSize], >+ received->strvalue,received->lvalue); >+ contentSize += received->lvalue; >+ } else { >+ error("too many Radius TLS fragments for EAP buffer!"); >+ result = ERROR_RC; >+ } >+ } >+ } >+ >+ /* reset avpair list */ >+ received = avpairs; >+ >+ /* free value pairs */ >+ rc_avpair_free(received); >+ rc_avpair_free(send); >+ >+ *content_len=contentSize; >+ >+ /* rc_auth() == OK_RC is NOT enough, we are >+ * not through all request/replies until.. */ >+ if(result == OK_RC && eaptls_content[0] == 3){ >+ >+ /* did we get an identity back from the server ?? */ >+ rstate.radius_acct_username[0] = '\0'; >+ >+ if(rstate.radius_cert_UPN[0] == '\0'){ >+ dbglog("RADIUS server did not return principalName!"); >+ result = ERROR_RC; >+ }else{ >+ dbglog("Extraction of principalName from RADIUS server succeeded!"); >+ strcpy(rstate.radius_acct_username, rstate.radius_cert_UPN); >+ } >+ >+ if(rstate.radius_acct_username[0] == '\0'){ >+ if(rstate.radius_cert_TCGID[0] == '\0'){ >+ error("RADIUS server did not return TCGID!"); >+ result = ERROR_RC; >+ }else{ >+ dbglog("Extraction of TCGID from RADIUS server succeeded!"); >+ strcpy(rstate.radius_acct_username, rstate.radius_cert_TCGID); >+ } >+ } >+ >+ if(rstate.radius_acct_username[0] == '\0'){ >+ if(rstate.radius_cert_CN[0] == '\0'){ >+ error("RADIUS server did not return commonName!"); >+ result = ERROR_RC; >+ }else{ >+ dbglog("Extraction of commonName from RADIUS succeeded!"); >+ strcpy(rstate.radius_acct_username, rstate.radius_cert_CN); >+ } >+ } >+ >+ if(rstate.radius_acct_username[0] == '\0'){ >+ strcat(rstate.user, "--NOT VERIFIED IN CERT!"); >+ }else{ >+ strcpy(rstate.user, rstate.radius_acct_username); >+ } >+ >+ dbglog("EAP TLS authentication succeeded for '%s'", rstate.user); >+ >+ result = OK_RC; >+ } >+ >+ if(result == OK_RC){ >+ return 0; >+ }else{ >+ return 1; >+ } >+} >+ >+/****************************************************************************************** >+ * Function: radius_snoop_received >+ * stores packets received by pppd >+ * in rstate for further use >+ ******************************************************************************************/ >+static void >+radius_snoop_received(unsigned char *p, int len) >+{ >+ rstate.ppp_snoop_data = p; >+ rstate.ppp_snoop_len = len; >+ >+} >+ >--- ppp-2.4.5-orig/pppd/plugins/radius/radius.c 2013-01-14 17:51:22.891407936 +0100 >+++ ppp-wegener-despace-stripnum/pppd/plugins/radius/radius.c 2013-01-15 15:23:28.741407706 +0100 >@@ -1509,6 +1509,11 @@ > /* Add User-Name attribute */ > type = PW_USER_NAME; > rc_avpair_add(&send, type, rstate.user, strlen(rstate.user)+1, VENDOR_NONE); >+ if (*remote_number) { >+ rc_avpair_add(&send, PW_CALLING_STATION_ID, remote_number, 0, >+ VENDOR_NONE); >+ } else if (ipparam) >+ rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE); > > /* Add EAP Message attribute with previously received EAP packet from peer */ > /* Maximum length of an eap message is 255 (type + length + String) */ >diff -rNu ppp-2.4.5-orig/pppd/plugins/radius/radiusclient.h ppp-wegener-despace-stripnum/pppd/plugins/radius/radiusclient.h >--- ppp-2.4.5-orig/pppd/plugins/radius/radiusclient.h 2009-11-16 23:26:07.000000000 +0100 >+++ ppp-wegener-despace-stripnum/pppd/plugins/radius/radiusclient.h 2013-01-15 15:25:15.280413341 +0100 >@@ -171,6 +171,12 @@ > /* From RFC 2869 */ > #define PW_ACCT_INTERIM_INTERVAL 85 /* integer */ > >+/* for eap tls */ >+ >+#define PW_EAP_MESSAGE 79 >+#define EAP_TLS_MAX_STRING_LEN 253 >+#define EAP_TLS_MAX_BUFFER_LEN 2048 >+ > /* Merit Experimental Extensions */ > > #define PW_USER_ID 222 /* string */ >@@ -181,6 +187,37 @@ > #define PW_SESSION_OCTETS_LIMIT 227 /* integer */ > #define PW_OCTETS_DIRECTION 228 /* integer */ > >+/* vendor specific attributes for cisco */ >+ >+#define PW_CISCO_AVPAIR 1 >+ >+/* vendor specific attributes for MS */ >+#define PW_MS_PRIMARY_DNS_SERVER 28 >+#define PW_MS_SECONDARY_DNS_SERVER 29 >+#define PW_MS_PRIMARY_NBNS_SERVER 30 >+#define PW_MS_SECONDARY_NBNS_SERVER 31 >+ >+/* vendor specific attributes for Siemens */ >+ >+#define PW_USERCERT_CN 221 >+#define PW_USERCERT_SN 222 >+#define PW_USERCERT_GN 223 >+#define PW_USERCERT_O 224 >+#define PW_USERCERT_OU 225 >+#define PW_USERCERT_ST 226 >+#define PW_USERCERT_L 227 >+#define PW_USERCERT_TITLE 228 >+#define PW_USERCERT_DESC 229 >+#define PW_USERCERT_NAME 230 >+#define PW_USERCERT_INITIALS 231 >+#define PW_USERCERT_PSEUDON 232 >+#define PW_USERCERT_ROLE 233 >+#define PW_USERCERT_UPN 240 >+#define PW_USERCERT_URI 241 >+#define PW_USERCERT_DNS 242 >+#define PW_USERCERT_EMAIL 243 >+#define PW_USERCERT_TCGID 244 >+ > /* Integer Translations */ > > /* SERVICE TYPES */ >@@ -290,8 +327,11 @@ > > > /* Vendor codes */ >+ > #define VENDOR_NONE (-1) >+#define VENDOR_CISCO 9 > #define VENDOR_MICROSOFT 311 >+#define VENDOR_SIEMENS 4329 > > /* Server data structures */ > >@@ -452,4 +492,9 @@ > > void rc_md5_calc __P((unsigned char *, unsigned char *, unsigned int)); > >+/* sendserver.c */ >+ >+/* 0 = NO EAP-Message-Authenticator needed. 1 = Needed */ >+extern int eap_tls_flag; >+ > #endif /* RADIUSCLIENT_H */ >diff -rNu ppp-2.4.5-orig/pppd/plugins/radius/sendserver.c ppp-wegener-despace-stripnum/pppd/plugins/radius/sendserver.c >--- ppp-2.4.5-orig/pppd/plugins/radius/sendserver.c 2009-11-16 23:26:07.000000000 +0100 >+++ ppp-wegener-despace-stripnum/pppd/plugins/radius/sendserver.c 2005-04-13 20:28:48.000000000 +0200 >@@ -12,15 +12,95 @@ > * If the file is missing contact me at lf@elemental.net > * and I'll send you a copy. > * >+ * EAP TLS support by: >+ * michael.heiart@freenet.de >+ * > */ > > #include <includes.h> > #include <radiusclient.h> > #include <pathnames.h> > >+#define MD5_HASH_SIZE 16 >+#define PW_EAP_MESSAGE 79 >+#define PW_MESSAGE_AUTHENTICATOR 80 >+ > static void rc_random_vector (unsigned char *); > static int rc_check_reply (AUTH_HDR *, int, char *, unsigned char *, unsigned char); > >+static void hmac_md5(unsigned char *text, /* pointer to data stream */ >+ int text_len, /* length of data stream */ >+ unsigned char *key, /* pointer to authentication key */ >+ int key_len, /* length of authentication key */ >+ u_char *digest); /* write result here */ >+ >+/* hmac_hash for EAP Message -Authenticator */ >+void MD5Init (); >+void MD5Update (); >+void MD5Final (); >+ >+/* forward declaration */ >+static void Transform (); >+ >+/* Data structure for MD5 (Message-Digest) computation */ >+typedef struct { >+ UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ >+ UINT4 buf[4]; /* scratch buffer */ >+ unsigned char in[64]; /* input buffer */ >+ unsigned char digest[16]; /* actual digest after MD5Final call */ >+} MD5_CTX; >+ >+static unsigned char PADDING[64] = { >+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, >+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 >+}; >+ >+/* F, G, H and I are basic MD5 functions */ >+#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) >+#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) >+#define H(x, y, z) ((x) ^ (y) ^ (z)) >+#define I(x, y, z) ((y) ^ ((x) | (~z))) >+ >+/* ROTATE_LEFT rotates x left n bits */ >+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) >+ >+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ >+/* Rotation is separate from addition to prevent recomputation */ >+#define FF(a, b, c, d, x, s, ac) \ >+ {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ >+ (a) = ROTATE_LEFT ((a), (s)); \ >+ (a) += (b); \ >+ } >+#define GG(a, b, c, d, x, s, ac) \ >+ {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ >+ (a) = ROTATE_LEFT ((a), (s)); \ >+ (a) += (b); \ >+ } >+#define HH(a, b, c, d, x, s, ac) \ >+ {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ >+ (a) = ROTATE_LEFT ((a), (s)); \ >+ (a) += (b); \ >+ } >+#define II(a, b, c, d, x, s, ac) \ >+ {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ >+ (a) = ROTATE_LEFT ((a), (s)); \ >+ (a) += (b); \ >+ } >+ >+#ifdef __STDC__ >+#define UL(x) x##U >+#else >+#define UL(x) x >+#endif >+ >+ >+ > /* > * Function: rc_pack_list > * >@@ -291,6 +371,70 @@ > sin->sin_addr.s_addr = htonl (auth_ipaddr); > sin->sin_port = htons ((unsigned short) data->svc_port); > >+ /* Build the hashMD5Input for an Message-Authenticator */ >+ if(eap_tls_flag == 1 && data->code != PW_ACCOUNTING_REQUEST) >+ { >+ /* Set Code and Id */ >+ unsigned char hashInput[2048]; >+ unsigned char *pHashInput = hashInput; >+ int inputSize = 0; >+ /* Length of the hole RADIUS packet for md5 hash */ >+ unsigned short slen = 0; >+ unsigned char hmac_md5hash[16]; >+ >+ >+ hashInput[0]=data->code; >+ hashInput[1]=data->seq_nbr; >+ inputSize = 2; >+ >+ /* The length of the data from auth->data /which are attributes) >+ + 18 Bytes for the Message Authenticator */ >+ slen = htons ((unsigned short) total_length + 18); >+ memcpy(pHashInput+inputSize,&slen,2); >+ inputSize += 2; >+ >+ /* The RADIUS authenticator !!THIS IS NOT THE MESSAGE AUTHENTICATOR!! */ >+ memcpy(pHashInput+inputSize,auth->vector,AUTH_VECTOR_LEN); >+ inputSize += AUTH_VECTOR_LEN; >+ >+ /* The Attributes WITHOUT the Message Authenticator */ >+ memcpy(pHashInput+inputSize,auth->data,total_length); >+ >+ /* total_length includes header and RADIUS authenticator */ >+ /* what we add are only the attributes. Therefore -20 */ >+ inputSize += total_length - 20; >+ >+ /* The Message Authenticator */ >+ >+ /* Set Attribuet Type Message Authenticator */ >+ hashInput[inputSize] = 80; >+ inputSize++; >+ >+ /* Set length */ >+ hashInput[inputSize] = 18; >+ inputSize++; >+ >+ /* Set the 16 bytes of the value to zero */ >+ /* do not make pHashInput higher because real hmac-MD5 hash will be copied here */ >+ memset(pHashInput+inputSize,0,16); >+ inputSize += 16; >+ >+ secretlen = strlen (secret); >+ hmac_md5((unsigned char*)pHashInput, inputSize,(unsigned char*)secret, secretlen, hmac_md5hash); >+ >+ /* the actual RADIUS PACKET needs the new length. >+ Packet will be 18 Bytes larger because of Message Authenticator */ >+ total_length += 18; >+ auth->length = htons ((unsigned short) total_length); >+ >+ /* copy the hmac_md5hash in the hashInput */ >+ memcpy(pHashInput+inputSize-16,hmac_md5hash,16); >+ >+ /* now the the hashInput from position 20 to end contains what data should be */ >+ memcpy(auth->data, pHashInput+20, total_length-20); >+ >+ } /* end if Message Authenticator */ >+ > for (;;) > { > sendto (sockfd, (char *) auth, (unsigned int) total_length, (int) 0, >@@ -370,13 +514,16 @@ > > if ((recv_auth->code == PW_ACCESS_ACCEPT) || > (recv_auth->code == PW_PASSWORD_ACK) || >- (recv_auth->code == PW_ACCOUNTING_RESPONSE)) >+ (recv_auth->code == PW_ACCOUNTING_RESPONSE)|| >+ (recv_auth->code == PW_ACCESS_CHALLENGE)||/* EAP TLS: RADIUS SERVER will send Challenge */ >+ (recv_auth->code ==PW_ACCESS_REJECT)) > { > result = OK_RC; > } > else > { > result = BADRESP_RC; >+ dbglog("rc_send_server thinks that this code is bad!!!"); > } > > return (result); >@@ -467,6 +614,12 @@ > return (BADRESP_RC); > } > >+ /* make sure that ACCESS_REJECT is flagged as BADRESP */ >+ if(auth->code == PW_ACCESS_REJECT){ >+ dbglog("rc_check_reply: received ACCESS REJECT"); >+ return (BADRESP_RC); >+ } >+ > return (OK_RC); > > } >@@ -518,3 +671,289 @@ > > return; > } >+ >+ >+/* The routine MD5Init initializes the message-digest context >+ mdContext. All fields are set to zero. >+ */ >+void MD5Init (mdContext) >+MD5_CTX *mdContext; >+{ >+ mdContext->i[0] = mdContext->i[1] = (UINT4)0; >+ >+ /* Load magic initialization constants. >+ */ >+ mdContext->buf[0] = (UINT4)0x67452301; >+ mdContext->buf[1] = (UINT4)0xefcdab89; >+ mdContext->buf[2] = (UINT4)0x98badcfe; >+ mdContext->buf[3] = (UINT4)0x10325476; >+} >+ >+/* The routine MD5Update updates the message-digest context to >+ account for the presence of each of the characters inBuf[0..inLen-1] >+ in the message whose digest is being computed. >+ */ >+void MD5Update (mdContext, inBuf, inLen) >+MD5_CTX *mdContext; >+unsigned char *inBuf; >+unsigned int inLen; >+{ >+ UINT4 in[16]; >+ int mdi; >+ unsigned int i, ii; >+ >+ /* compute number of bytes mod 64 */ >+ mdi = (int)((mdContext->i[0] >> 3) & 0x3F); >+ >+ /* update number of bits */ >+ if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0]) >+ mdContext->i[1]++; >+ mdContext->i[0] += ((UINT4)inLen << 3); >+ mdContext->i[1] += ((UINT4)inLen >> 29); >+ >+ while (inLen--) { >+ /* add new character to buffer, increment mdi */ >+ mdContext->in[mdi++] = *inBuf++; >+ >+ /* transform if necessary */ >+ if (mdi == 0x40) { >+ for (i = 0, ii = 0; i < 16; i++, ii += 4) >+ in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | >+ (((UINT4)mdContext->in[ii+2]) << 16) | >+ (((UINT4)mdContext->in[ii+1]) << 8) | >+ ((UINT4)mdContext->in[ii]); >+ Transform (mdContext->buf, in); >+ mdi = 0; >+ } >+ } >+} >+ >+/* The routine MD5Final terminates the message-digest computation and >+ ends with the desired message digest in mdContext->digest[0...15]. >+ */ >+void MD5Final (hash, mdContext) >+unsigned char hash[]; >+MD5_CTX *mdContext; >+{ >+ UINT4 in[16]; >+ int mdi; >+ unsigned int i, ii; >+ unsigned int padLen; >+ >+ /* save number of bits */ >+ in[14] = mdContext->i[0]; >+ in[15] = mdContext->i[1]; >+ >+ /* compute number of bytes mod 64 */ >+ mdi = (int)((mdContext->i[0] >> 3) & 0x3F); >+ >+ /* pad out to 56 mod 64 */ >+ padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); >+ MD5Update (mdContext, PADDING, padLen); >+ >+ /* append length in bits and transform */ >+ for (i = 0, ii = 0; i < 14; i++, ii += 4) >+ in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | >+ (((UINT4)mdContext->in[ii+2]) << 16) | >+ (((UINT4)mdContext->in[ii+1]) << 8) | >+ ((UINT4)mdContext->in[ii]); >+ Transform (mdContext->buf, in); >+ >+ /* store buffer in digest */ >+ for (i = 0, ii = 0; i < 4; i++, ii += 4) { >+ mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); >+ mdContext->digest[ii+1] = >+ (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); >+ mdContext->digest[ii+2] = >+ (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); >+ mdContext->digest[ii+3] = >+ (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); >+ } >+ memcpy(hash, mdContext->digest, 16); >+} >+ >+/* Basic MD5 step. Transforms buf based on in. >+ */ >+static void Transform (buf, in) >+UINT4 *buf; >+UINT4 *in; >+{ >+ UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; >+ >+ /* Round 1 */ >+#define S11 7 >+#define S12 12 >+#define S13 17 >+#define S14 22 >+ FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */ >+ FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */ >+ FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */ >+ FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */ >+ FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */ >+ FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */ >+ FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */ >+ FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */ >+ FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */ >+ FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */ >+ FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */ >+ FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */ >+ FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */ >+ FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */ >+ FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */ >+ FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */ >+ >+ /* Round 2 */ >+#define S21 5 >+#define S22 9 >+#define S23 14 >+#define S24 20 >+ GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */ >+ GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */ >+ GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */ >+ GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */ >+ GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */ >+ GG ( d, a, b, c, in[10], S22, UL( 38016083)); /* 22 */ >+ GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */ >+ GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */ >+ GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */ >+ GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */ >+ GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */ >+ GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */ >+ GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */ >+ GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */ >+ GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */ >+ GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */ >+ >+ /* Round 3 */ >+#define S31 4 >+#define S32 11 >+#define S33 16 >+#define S34 23 >+ HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */ >+ HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */ >+ HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */ >+ HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */ >+ HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */ >+ HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */ >+ HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */ >+ HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */ >+ HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */ >+ HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */ >+ HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */ >+ HH ( b, c, d, a, in[ 6], S34, UL( 76029189)); /* 44 */ >+ HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */ >+ HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */ >+ HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */ >+ HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */ >+ >+ /* Round 4 */ >+#define S41 6 >+#define S42 10 >+#define S43 15 >+#define S44 21 >+ II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */ >+ II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */ >+ II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */ >+ II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */ >+ II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */ >+ II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */ >+ II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */ >+ II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */ >+ II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */ >+ II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */ >+ II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */ >+ II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */ >+ II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */ >+ II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */ >+ II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */ >+ II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */ >+ >+ buf[0] += a; >+ buf[1] += b; >+ buf[2] += c; >+ buf[3] += d; >+} >+ >+/* >+** Function: hmac_md5 >+*/ >+ >+static void >+hmac_md5(text, text_len, key, key_len, digest) >+unsigned char* text; /* pointer to data stream */ >+int text_len; /* length of data stream */ >+unsigned char* key; /* pointer to authentication key */ >+int key_len; /* length of authentication key */ >+u_char* digest; /* caller digest to be filled in */ >+ >+{ >+ MD5_CTX context; >+ unsigned char k_ipad[65]; /* inner padding - >+ * key XORd with ipad >+ */ >+ unsigned char k_opad[65]; /* outer padding - >+ * key XORd with opad >+ */ >+ unsigned char tk[16]; >+ int i; >+ /* if key is longer than 64 bytes reset it to key=MD5(key) */ >+ if (key_len > 64) { >+ >+ MD5_CTX tctx; >+ >+ MD5Init(&tctx); >+ MD5Update(&tctx, key, key_len); >+ MD5Final(tk, &tctx); >+ >+ key = tk; >+ key_len = 16; >+ } >+ >+ /* >+ * the HMAC_MD5 transform looks like: >+ * >+ * MD5(K XOR opad, MD5(K XOR ipad, text)) >+ * >+ * where K is an n byte key >+ * ipad is the byte 0x36 repeated 64 times >+ >+ * opad is the byte 0x5c repeated 64 times >+ * and text is the data being protected >+ */ >+ >+ /* start out by storing key in pads */ >+ bzero( k_ipad, sizeof k_ipad); >+ bzero( k_opad, sizeof k_opad); >+ bcopy( key, k_ipad, key_len); >+ bcopy( key, k_opad, key_len); >+ >+ /* XOR key with ipad and opad values */ >+ for (i=0; i<64; i++) { >+ k_ipad[i] ^= 0x36; >+ k_opad[i] ^= 0x5c; >+ } >+ >+ /* >+ * perform inner MD5 >+ */ >+ MD5Init(&context); /* init context for 1st >+ * pass */ >+ >+ MD5Update(&context, k_ipad, 64); /* start with inner pad */ >+ >+ MD5Update(&context, text, text_len); /* then text of datagram */ >+ >+ MD5Final(digest, &context); /* finish up 1st pass */ >+ >+ /* >+ * perform outer MD5 >+ */ >+ MD5Init(&context); /* init context for 2nd >+ * pass */ >+ >+ MD5Update(&context, k_opad, 64); /* start with outer pad */ >+ >+ MD5Update(&context, digest, 16); /* then results of 1st >+ * hash */ >+ MD5Final(digest, &context); /* finish up 2nd pass */ >+} >diff -uN ppp-2.4.5-orig/README.eap-tls-client ppp-wegener-despace-stripnum/README.eap-tls-client >--- ppp-2.4.5-orig/README.eap-tls-client 1970-01-01 01:00:00.000000000 +0100 >+++ ppp-wegener-despace-stripnum/README.eap-tls-client 2005-04-15 14:22:25.000000000 +0200 >@@ -0,0 +1,244 @@ >+EAP TLS client mode extension for the LINUX PPPD >+================================================== >+ >+Autor: Michael Joosten >+ michael.joosten@c-lab.de.de >+ >+Copyright (C) (2005) Michael Joosten >+ >+This program is free software; you can redistribute it and/or >+modify it under the terms of the GNU General Public License >+as published by the Free Software Foundation; either version 2 >+of the License, or (at your option) any later version. >+ >+This program is distributed in the hope that it will be useful, >+but WITHOUT ANY WARRANTY; without even the implied warranty of >+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+GNU General Public License for more details. >+ >+You should have received a copy of the GNU General Public License >+along with this program; if not, write to the Free Software >+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. >+ >+ >+Overview >+======== >+ >+Primarily to test the server-side extension of pppd and the RADIUS >+plugin, the client side was also extended to provide EAP TLS >+authentication. EAP TLS is currently mostly used for VPNs to support mobile >+clients using Microsoft operating systems, as this is the strongest >+authentication method that is supported out-of-the-box in Windows 2000 >+and XP. Due to the nature of TLS client authentication, this >+requires the use of certificates, namely user and CA certificates and >+the private key of the user certificate. This is what you usually get >+from the VPN operator as a legitimate user. >+ >+In a Microsoft compatible VPN setup, IPSec is used as secure tunnel >+between the mobile client and the VPN gateway, usually also with >+certicates (host certificate). Over this tunnel, L2TP is used to >+encapsulate not only IP, but also other layer 2 protocols >+(e.g. NetBios, IPX, etc). In addition to the host authentification, a >+separate client authentification takes place using EAP TLS, before the >+actual data can pass between the mobile client and the VPN using >+PPP. Therefore, a suitable setup for a Linux client requires >+subsystems for IPSec, i.e. FreeSWAN/OpenSWAN, L2TP, i.e rp-l2tpd or >+l2tpd, and PPP, of course 8-). In this setup, l2tpd acts as client and >+initiates a tunnel connection via the IPSec connection to the VPN >+gateway. l2tpd then uses pppd to authenticate the client to the >+gateway and to set up the point-to-point network connection to the VPN. >+ >+ >+Implementation >+============== >+ >+To provide the necessary client functionality, the eap.c module was >+extended with the necessary hooks for TLS, which are implemented in >+eaptls.c. TLS requires OpenSSL libraries, and is currently a >+compile-time option in pppd's Makefile (USE_TLS_PEER=y). You should >+use openssl-0.9.7a at least. In addition, a number of configuration >+options must be set. >+ >+For detailed information about EAP TLS and the necessary steps in the >+communication between the authenticator (e.g., pppd with the extended >+radius plugin) and the RADIUS server on the one side and the client >+and the authenticator on the other please read: >+ >+ RFC 2716 >+ RFC 3579 >+ RFC 2104 >+ RFC 2866 >+ RFC 2869 >+ >+Client <------> Authenticator <------------> RADIUS Server >+e.g. pppd <------> ppp (extended pppd) <-------------> FreeRadius >+ >+ >+ >+Configuration as client >+======================= >+ >+1. PKI infrastructure >+---------------------- >+You will need a user certificate with an associated private key, and >+the CA (Certification Authority) root certificate, which signed the >+user's certificate. They all come in files, either in PEM (Privacy >+Enhanced Mail) format (*.pem), PKCS#12 (*.p12) or as raw ASN.1 (*.der) >+data. Often, the client certificate file also contains the private >+key. The private key is always encrypted and requires a separate >+password. To sum it up, you need: >+a) CA certificate file (e.g. cacert.pem) >+b) user certicate file (e.g. usercert.pem) >+c) user private key file, optional (e.g. userkey.pem) >+d) the password to the private key file >+ >+This implementation is able to use PEM and DER formats. User >+certificates in PKCS#12 format must be converted to PEM: >+ $ openssl pkcs12 -in usercert.p12 -out usercert.pem >+The openssl utility requires you to enter three times the so-called transport >+password. >+ >+2. EAP TLS configuration options >+-------------------------------- >+In order to provide the certification data to the TLS subsystem, the >+following options are introduced: >+- eap-user-cert: Path to X509 user certificate file >+- eap-user-key : Path to X509 user private key file, >+ can be the same as eap-user-cert >+- eap-root-cert: Path to X509 root (CA) certificate file >+- eap-root-dir : Directory of X509 root (CA) certificate files >+- eap-crl-dir : Directory of X509 certificate revocation files >+ >+In addition, the user's name for the authentication is needed in the >+EAP protocol. Since the authenticator is probably using the >+certificate to check for a match, this name should usually be the >+so-called Common Name (CN) of the certificate's Subject. >+Next, the private key password is required. This is provided by either >+by the 'password' option, or through the password plugins which >+provide the means to pass in the password from an external program or >+even a opened file descriptor. (See the plugin subdirectory and the >+manual page). >+Therefore, the following options are also required: >+- user "forename surname" >+- password "my private key passphrase" >+ >+ >+Installation of the new PPP/PPPD >+================================ >+ >+Install >+------- >+The new version of the pppd contains a makefile that has the necessary >+compile options disabled. Uncomment the line >+ #USE_TLS_PEER=y >+to build pppd with EAP TLS client mode. You might also add >+options for different installation directories of the OpenSSL include >+files and libraries than /usr/include and /usr/lib, like a source code >+installation in /usr/local/openssl. >+ >+./configure >+make >+make install >+ >+ >+ppp options for EAP TLS client mode: >+----------- >+ppp/options >+Edit the /etc/ppp/options file: >+# MUST match the CN in the user's certificate ! >+user "John Doe" >+password "rue morgue" >+# authenticator wants the peer to authenticate with EAP >+ >+# no compression here >+noccp >+ >+# no encryption..we have the ipsec tunnel >+nomppe >+ >+# have a look at the packets >+#debug >+ >+# accept IPs for both sides of the point-to-point link from gateway >+ipcp-accept-local >+ipcp-accept-remote >+ >+# EAP TLS certificate setup >+eap-user-cert /etc/ppp/certs/users/client-cert.pem >+eap-user-key /etc/ppp/certs/users/client-cert.pem >+eap-root-cert /etc/ppp/certs/root.pem >+eap-root-dir /etc/ppp/certs >+eap-crl-dir /etc/ppp/certs/crls >+ >+Hint: The file etc/ppp/options.EAPTLS-client of this ppp version contains >+this example configuration. >+As you can see, in this example the user's certificate file also >+contains the private key. >+ >+Additional configurations of rp-l2tpd and IPSec (Free/OpenSWAN) >+=============================================================== >+ >+IPSec >+----- >+Similar to the user certificates for pppd, you will probably need >+host/node specific certificates for the IPSec tunnel. >+ >+See http://www.natecarlson.com/linux/ipsec-x509.php >+for a step by step guide of a FreeSwan installation, because the >+configuration is very site-specific. >+ >+L2TP Daemon >+----------- >+The implementation was tested with rp-l2tp. l2tpd is normally used on >+the server side, but can also be used as client to initiate a tunnel >+connection. rp-l2tpd provide a control program, l2tp-control, that >+passes control messages to the actual L2TP daemon running in the >+background. The necessary configuration file for a client-mode tunnel >+looks like this: >+/etc/l2tp/l2tp.conf: >+============================================================= >+# Global section (by default, we start in global mode) >+global >+ >+# Load handlers >+load-handler "sync-pppd.so" >+load-handler "cmd.so" >+ >+# Bind address >+listen-port 1701 >+ >+# Configure the sync-pppd handler. You MUST have a "section sync-pppd" line >+# even if you don't set any options. >+section sync-pppd >+# lns-pppd-opts "require-chap ms-dns 149.246.222.145 lcp-echo-interval 30 lcp-echo-failure >+6" >+ >+section peer >+# replace the vpn-gateway with the gateway's hostname or IP address >+peer vpn-gateway >+port 1701 >+lac-handler sync-pppd >+lns-handler sync-pppd >+hide-avps no >+ >+# Configure the cmd handler. You MUST have a "section cmd" line >+# even if you don't set any options. >+# this is needed to start the tunnel manually via "l2tp-control"! >+section cmd >+ >+============================================= >+ >+The tunnel is started by running "l2tp-control": >+ $ l2tp-control "start-session vpn-gateway" >+ >+Note the enclosing "", they are needed because this utility accepts >+only a single argument. Don't forget to replace 'vpn-gateway' with the >+actual host name. >+l2tpd creates the tunnel via UDP, and starts pppd to negotiate the >+link options, authenticate the user and create a ppp0 network interface for the >+point-to-point link. It is advisable for debugging to add an >+additional log file for pppd in /etc/syslog.conf: >+ >+daemon.debug /var/log/pppd >+ >+as first line. >diff -uN ppp-2.4.5-orig/README.eap-tls_plus_addOns ppp-wegener-despace-stripnum/README.eap-tls_plus_addOns >--- ppp-2.4.5-orig/README.eap-tls_plus_addOns 1970-01-01 01:00:00.000000000 +0100 >+++ ppp-wegener-despace-stripnum/README.eap-tls_plus_addOns 2005-04-15 14:35:50.000000000 +0200 >@@ -0,0 +1,429 @@ >+EAP TLS extension for the LINUX PPPD Radius-PlugIn >+================================================== >+ >+Autor: Michael Heiart >+ michael.heiart@freenet.de >+ >+!!! This document describes the server part of the pppd. >+ Read the file README.eap-tls-client for information about the >+ client part of the pppd !!! >+ >+Copyright (C) (2005) Michael Heiart >+ >+This program is free software; you can redistribute it and/or >+modify it under the terms of the GNU General Public License >+as published by the Free Software Foundation; either version 2 >+of the License, or (at your option) any later version. >+ >+This program is distributed in the hope that it will be useful, >+but WITHOUT ANY WARRANTY; without even the implied warranty of >+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+GNU General Public License for more details. >+ >+You should have received a copy of the GNU General Public License >+along with this program; if not, write to the Free Software >+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. >+ >+ >+Overview >+======== >+ >+Target >+------ >+The extension of the radius plugin described >+in this document, now provides EAP TLS authentication on a RADIUS >+server and in addition IP Pool functionality, IP pools for user >+groups, pppd accounting, certificate based usernames >+for accounting. >+Certificate based username extraction is only available in connection with >+a patch for FreeRadius 1 which sends the username in a attribute value pair. >+ >+ >+How it works >+------------ >+The entry point for the EAP TLS extension is the class eap.c of the >+pppd's radius plugin which contains the state machine for EAP based >+authentications. In eap.c it is possible to use hooks which can point >+to methods in other modules. >+ >+For EAP TLS a hook was created which points to the new method >+radius_eaptls(..) in pppd/plugins/radius/radius.c. radius_eaptls(..) >+uses a newly extended version of the radius client library to >+communicate with a RADIUS server. >+ >+For more information about the pppd, its plugins and hooks please read >+the documentation of the ppp. >+ >+For detailed information about EAP TLS and the necessary steps in the >+communication between the authenticator (our pppd with the extended >+radius plugin) and the RADIUS server on the one side and the client >+and the authenticator on the other please read: >+ >+ RFC 2716 >+ RFC 3579 >+ RFC 2104 >+ RFC 2866 >+ RFC 2869 >+ >+Client <------> Authenticator <------------> RADIUS Server >+e.g. XP <------> ppp (extended pppd) <-------------> FreeRadius >+ >+ >+The New Functionality >+===================== >+ >+ >+EAP TLS Authentication: >+----------------------- >+Mutual certificate based authentication. >+ >+IP-Pool management (optional): >+------------------------------ >+The pppd now has its own IPPOOL management. The pppd can assign IP >+addresses for the clients which are authenticated by CHAP, PAP or EAP >+TLS. (see: etc/ppp/ippool.txt) The advantage over a RADIUS handled >+pool is that one central point manages the IP addresses and that the >+pool can be easily cleaned up if a connection breaks down. In >+contrast to this simple solution the IP Pool management by RADIUS >+servers(s) can become quite complex. Especially if more that one >+RADIUS server manages IP addresses. (Hint: FreeRadius currently can >+not handle the IP pools if EAP TLS is active!) >+ >+ >+Assigning a specific IP pool for a user: >+------------------------------------------------ >+The pppd can handle different IP pools. >+A specific pool can be assigned in the user's file of the RADIUS server. >+The pppd EAP TLS extension can replavce Cisco AP and therefore uses the CISCO syntax >+for attirbute value pairs: >+ >+Cisco-AVPair += "ip:addr-pool=examplePool", >+ >+ >+Extraction of usernames: >+------------------------ >+For the accounting the username must be unique and correct. >+Therefore the EAP TLS extension of the pppd can use a username >+that is extracted from the certificate data. >+The extration of the name itself must be done by the RADIUS server. >+We provide a patch for FreeRadius 1 which offers the username extraction alongside >+with new dictionaries for this purpose. >+ >+ >+Requirements >+============ >+ >+ >+System OS: Linux >+---------------- >+The pppd plugin extension was tested with SUSE Linux 9.0, Suse 9.2 >+and RedHat 9.0 >+ >+ >+OpenSSL: OpenSSL 0.9.7d >+----------------------- >+For the generation of certificates for he client and the RADIUS >+server, openssl is necessary. Keep in mind that only newer versions >+of openssl are able to set the enhanced usage keys which are necessary >+for EAP TLS authentications of Windows XP Clients. >+ >+ >+IPSec: Freeswan 1.99 (optional) >+------------------------------- >+MS XP Clients can use l2tp over IPsec for VPN connections. If you >+want to use MS XP Clients it is necessary to install IPsec on your >+authenticator. Currently VPN with l2tp over IPsec is a solution that >+Windows XP supports without the need of any additional software. >+ >+See http://www.natecarlson.com/linux/ipsec-x509.php to learn more >+about the installation of IPsec under Linux. >+ >+ >+L2TP: rp-l2tp >+------------- >+During development and functional testing the rp-l2tp implementation was used. >+Read the manual of rp-l2tp for details. >+See: http://sourceforge.net/projects/rp-l2tp/ >+ >+ >+L2TP: l2tpd >+----------- >+l2tpd is also known to be working. You can download the latest RPM from >+http://www.jacco2.dds.nl/networking/SRPMS/ >+ >+ >+PPP: PPP with this extension of the radius plugin >+------------------------------------------------------- >+This version of ppp. >+ >+ >+FreeRadius 1.0.1 >+---------------- >+The new plugin was tested with FreeRADIUS 1.0.1. >+For details read the manual that comes with FreeRadius. >+ >+See http://www.natecarlson.com/linux/ipsec-x509.php >+for a step by step guide of a FreeSwan installation. >+ >+You must install our FreeRadius patch for username extraction, >+if you want the pppd to use certificate based username for the accounting. >+ >+ >+Installation of the new PPP/PPPD >+================================ >+ >+ >+Install >+------- >+The new version of the pppd contains a makefile that by default enables >+the radius plugin with the new EAP TLS features. >+ >+./configure >+make >+make install >+ >+ >+ppp options >+----------- >+ppp/options >+Edit the /etc/ppp/options file: >+ >+auth >+# the client MUST authenticate >+ >+require-eap >+# the authentication MUST be done with EAP >+ >+refuse-eap >+# the authenticator (pppd) does NOT authenticate itself (optional) >+ >+noccp >+# disable compression >+ >+nomppe >+# disable encrytion of payload >+ (with l2tp over ipsec we already have the ipsec tunnel) >+ >+# uncomment for more logging >+#debug >+ >+a.b.c.d:e.f.g.h: >+#a.b.c.d ist he address of the authenticator (this ppp(d)) >+#e.f.g.h is the default address for clients which authenticate >+# over your authenticator. >+#For example: 129.103.93.53:129.129.129.117 >+#The default client address (e.f.g.h) will be omitted if the IP pool >+# feature is enabled. >+ >+Hint: The file etc/ppp/options.EAPTLS of this ppp version contains >+this example configuration. >+ >+ >+The IP-POOL >+----------- >+The new pppd radius plugin can manage a pool of IP addresses. >+An address from this pool can be assigned to those clients which >+successfully authenticated by EAP TLS, PAP or CHAP. >+ >+The address range, the addresses in use and those addresses that >+became free because the connection to a client terminated are stored >+in the file ippool.txt. >+ >+Example etc/ppp/ippool.txt: >+fffffffff >+s129.129.129.117 >+e129.129.129.120 >+x129.129.129.117 >+i129.129.129.118 >+End >+ >+The address marked with 's' is the beginning of the IP address range. >+The address marked with 'e' is the end of the IP address range. >+ >+An address marked with an 'x' has been assigned to a client and became >+free after the connection to the client terminated. >+ >+An address marked with an 'i' is currently in use for a connection between >+a client and the authenticator (pppd). >+ >+ >+Enabling the pppd's IP-Pool >+--------------------------- >+If the file etc/ppp/ippool.txt exists the pool will be enabled during >+the initialization of the pppd. If the file does not exist the >+default IP Address for clients defined in the options file >+(/etc/ppp/options) of the ppp will be used. >+ >+Some Remarks: The pool will be blocked, while a pppd process uses it, >+by writing the process id of this pppd process in the first line of >+the pool. Each time a pppd process tries to use the pool, it checks, >+that the process id which blocks the pool is not stale. If the >+process which should belong to this pid does not exist any more, the >+pool will be unblocked by the new pppd process. If the blocking >+process is still alive the new pppd process will wait until the other >+process has finished its work with the pool. >+ >+To make it short: Do not edit the pool file unless you really >+terminate the ppp and want to force the clients to initiate new >+connections. In this case you want to remove the old entries of IP >+addresses in use. Otherwise let the pppd manage the pool. Even if >+someone pulls out the network cable the ppp will unblock the IP >+address(es) that was/were used for this/these connection(s). !!!Never >+unblock an IP address that is still in use for a connection!!! >+ >+ >+IP-Pools For Groups of Users >+---------------------------- >+It is mandatory to have a default IP-Pool file for the activation of >+the pppd's IP pool (/etc/ppp/ippool.txt). If this file does >+NOT exist, all IP pool functionality of the pppd will be disabled. If >+the use of the pppd's IP pool is enabled, it is possible to >+use different IP pools depending on the group a user belongs to. >+ >+This group must be defined in the user file of the RADIUS server. >+The RADIUS server transmits this class to the pppd in a RADIUS EAP >+Attribute if the authentication of the client-user succeeded. Here is >+an example for a RADIUS user file which assigns the user class >+"pennypincher" to a user: >+ >+"Bill Scrooge" >+ Service-Type = Framed-User, >+ Cisco-AVPair += "ip:addr-pool=pennypincher", >+ Cisco-AVPair += "ip:dns-servers=157.163.180.24 139.25.207.172", >+ Cisco-AVPair += "ip:wins-servers=146.254.60.128 1.1.1.1",0 >+ Framed-Protocol = PPP, >+ Idle-Timeout = 3456, >+ MS-Primary-DNS-Server = 0.0.0.0, >+ MS-Secondary-DNS-Server = 0.0.0.0, >+ MS-Primary-NBNS-Server = 0.0.0.0, >+ MS-Secondary-NBNS-Server = 0.0.0, >+ Framed-Compression = Van-Jacobsen-TCP-IP, >+ Fall-Through = No >+ >+The IP-pool file for the user class 'pennypincher' will be >+/etc/ppp/pennypincher.txt. >+ >+ >+RADIUS side accounting >+---------------------- >+The pppd triggers the RADIUS accounting with client username and the >+IP Address assigned to the client: >+ >+/usr/var/log/radius/radacct/detail-xyz >+ >+Wed Aug 11 16:49:01 2004 >+ Acct-Session-Id = ... >+ Framed-IP-Address = 129.129.129.117 >+ Acct-Status-Type = Start >+ User ... >+ ... >+ >+Wed Aug 11 17:59:15 2004 >+ Acct-Session-Id = ... >+ Framed-IP-Address = 129.129.129.117 >+ Acct-Status-Type = Stop >+ User ... >+ ... >+ >+ >+Simple PPPD Accounting >+---------------------- >+If the pppd IP pool is enabled (by having an ippool.txt file in >+etc/ppp/) the pppd accounting is enabled, too. Under var/run/ccert >+the pppd creates folders for each user group and writes files in this >+folder with a filename that corresponds with the IP Address that was >+assigned to a client. The only content of this file is the username >+of the client user. Currently the pppd accounting does not contain >+time stamp information for logon and logoff because billing has not >+been in scope during the development of the pppd accounting method. >+Furthermore the pppd accounting files for a connection will be removed >+immediately after the connection's termination. To make it short: The >+pppd accounting generates an overview of IP Addresses that are in use >+and shows which user of which user group uses a specific IP Address. >+ >+ >+Uniqueness Of Usernames/ Extraction of usernames from Client >+Certificates >+------------------------------------------------------------------------- >+The pppd can use a username which the RADIUS server extracts from the >+user's certificate (Uniqpe Principal Name UPN, TCGID or CN). >+This username must be send from the RADIUS server within an attribute value pair. >+ >+If the RADIUS server does not sent one of the above mentioned names >+the username sent by the client will be marked as 'not verified'. >+ >+ >+EAP TLS Configuration Of The RADIUS Server >+------------------------------------------ >+In eap.conf change the configuration of your RADIUS server to enable >+the use of EAP TLS. >+Example: If you use FreeRadius you must edit the file eap.conf >+ >+# set authentication type to EAP TLS >+eap{ >+ default-eap-type = tls >+ ... >+} >+ >+# Edit the certificate pathes in eap.conf to make them point to your >+# certificates >+tls { >+ private_key_file = ... >+ Certificate_file = ... >+ CA_file = ... >+} >+ >+Some remarks: >+On the RADIUS server for EAP TLS a server-cert.pem and a root.pem >+are necessary. >+ >+On the client side a client-cert.p12 and a root.der are necessary. >+ >+All these certificates must be signed by the same certification >+authority! On XP clients the user's certificates for the client must >+be stored in the user's certificate store and NOT in the machine's >+certificate store. To control the certificate stores on Windows XP >+systems choose: Run->mmc->add snapIn->certificate->user >+certificates..... >+ >+ >+Dictionaries >+------------ >+The RADIUS dictionaries must be updated to the versions that come with >+this new version of the pppd. Otherwise the RADIUS server will fail >+with misleading error messages. A lot of EAP TLS relevant attributes >+have been added to the dictionaries. !!!UPDATE THE DICTIONARY FILES >+ON YOUR RADIUS SERVER!!! Find dictionaries containing all necessary >+attributes in the folder 'newDictionaries' of this ppp version. >+ >+Both RADIUS dictionaries and radiusclient dictionaries must be up to date. >+ >+ >+Starting the RADIUS Server >+-------------------------- >+Start the RADIUS Server with radiusd -XA and watch out for messages >+concerning the rlm_tls module. Only if this module starts properly >+the EAP TLS part of your RADIUS server will do what you want. >+ >+ >+Microsoft Internet Authentication Service (IAS) >+=============================================== >+ >+EAP-TLS is also supported by the IAS from Microsoft, you can use your >+certificates in your active directory to authenticate >+certificates. There is one issue with this: The IAS sets for EAP >+authentification the session timeout to 30 seconds by default, we >+don't know why! Select the following settings: >+ >+* Policy name: VPN accesss >+ >+* User or Group: Select Group, and then specify the VPN group. >+ >+* Authentication methods: Select Smart Card or other Certificate. >+ >+* Policy Encryption Level: none. >+ >+* Permission: Grant remote access permission >+ >+* Profile settings, Dial-in Constraints tab: Select the Minutes client >+ can be connected check box, and then type 1440 (1 day). >--- ppp-2.4.5-orig/pppd/plugins/radius/radattr.c 2004-10-28 01:24:40.000000000 +0100 >+++ ppp-2.4.5-multilink/pppd/plugins/radius/radattr.c 2009-11-30 10:34:22.000000000 +0000 >@@ -22,11 +22,17 @@ static char const RCSID[] = > #include <stdio.h> > > extern void (*radius_attributes_hook)(VALUE_PAIR *); >+void (*radattr_attributes_oldhook)(VALUE_PAIR *) = NULL; >+void (*radattr_ip_choose_oldhook) __P((u_int32_t *)) = NULL; > static void print_attributes(VALUE_PAIR *); > static void cleanup(void *opaque, int arg); > > char pppd_version[] = VERSION; > >+char fname[512]; >+VALUE_PAIR *saved_vp=NULL; >+static radattr_ip_choose_hooked=0; >+ > /********************************************************************** > * %FUNCTION: plugin_init > * %ARGUMENTS: >@@ -39,8 +45,11 @@ char pppd_version[] = VERSION; > void > plugin_init(void) > { >+ radattr_attributes_oldhook = radius_attributes_hook; > radius_attributes_hook = print_attributes; > >+ fname[0]='\0'; >+ > #if 0 > /* calling cleanup() on link down is problematic because print_attributes() > is called only after PAP or CHAP authentication, but not when the link >@@ -63,11 +72,8 @@ plugin_init(void) > * Prints the attribute pairs to /var/run/radattr.pppN. Each line of the > * file contains "name value" pairs. > ***********************************************************************/ >-static void >-print_attributes(VALUE_PAIR *vp) >-{ >+void print_attributes_to_file(VALUE_PAIR *vp) { > FILE *fp; >- char fname[512]; > char name[2048]; > char value[2048]; > int cnt = 0; >@@ -90,6 +96,47 @@ print_attributes(VALUE_PAIR *vp) > dbglog("RADATTR plugin wrote %d line(s) to file %s.", cnt, fname); > } > >+ >+static void radattr_ip_choose_hook(u_int32_t *addrp) { >+ if (saved_vp && ifname[0]) { >+ /* If multilink is enabled this is first available >+ hook after setting ifname. >+ Thankfully IPCP is first network protocol to be started >+ and this hook will get called before any other >+ protocols are started. >+ We're assuming IP is always enabled if multilink is! */ >+ >+ print_attributes_to_file(saved_vp); >+ rc_avpair_free(saved_vp); >+ saved_vp=NULL; >+ } >+ if (radattr_ip_choose_oldhook) { >+ radattr_ip_choose_oldhook(addrp); >+ } >+} >+ >+static void >+print_attributes(VALUE_PAIR *vp) >+{ >+ >+ if (radattr_attributes_oldhook) { >+ radattr_attributes_oldhook(vp); >+ } >+ >+ if (ifname[0]) { >+ print_attributes_to_file(vp); >+ } else { >+ if (saved_vp) >+ rc_avpair_free(saved_vp); >+ saved_vp=rc_avpair_copy(vp); >+ if (saved_vp && ! radattr_ip_choose_hooked) { >+ radattr_ip_choose_oldhook=ip_choose_hook; >+ ip_choose_hook=radattr_ip_choose_hook; >+ radattr_ip_choose_hooked=1; >+ } >+ } >+} >+ > /********************************************************************** > * %FUNCTION: cleanup > * %ARGUMENTS: >@@ -103,9 +150,8 @@ print_attributes(VALUE_PAIR *vp) > static void > cleanup(void *opaque, int arg) > { >- char fname[512]; >- >- slprintf(fname, sizeof(fname), "/var/run/radattr.%s", ifname); >+ if (fname[0]) { > (void) remove(fname); > dbglog("RADATTR plugin removed file %s.", fname); >+ } > } >--- ppp-2.4.5-orig/pppd/plugins/radius/radiusclient.h 2013-01-15 20:54:50.893422864 +0100 >+++ ppp-2.4.5-new/pppd/plugins/radius/radiusclient.h 2013-01-15 20:59:11.392411679 +0100 >@@ -31,7 +31,7 @@ > #define AUTH_VECTOR_LEN 16 > #define AUTH_PASS_LEN (3 * 16) /* multiple of 16 */ > #define AUTH_ID_LEN 64 >-#define AUTH_STRING_LEN 128 /* maximum of 253 */ >+#define AUTH_STRING_LEN 253 /* maximum of 253 */ > > #define BUFFER_LEN 8192 > >--- ppp-2.4.5-orig/pppd/eap.h 2013-01-15 21:02:14.627407862 +0100 >+++ ppp-2.4.5-new/pppd/eap.h 2013-01-15 21:09:55.703410000 +0100 >@@ -142,7 +142,7 @@ > * Timeouts. > */ > #define EAP_DEFTIMEOUT 3 /* Timeout (seconds) for rexmit */ >-#define EAP_DEFTRANSMITS 10 /* max # times to transmit */ >+#define EAP_DEFTRANSMITS 20 /* max # times to transmit */ > #define EAP_DEFREQTIME 20 /* Time to wait for peer request */ > #define EAP_DEFALLOWREQ 20 /* max # times to accept requests */ > >--- ppp-2.4.5-orig/pppd/plugins/radius/radius.c 2013-01-15 22:21:41.518782305 +0100 >+++ ppp-2.4.5-new/pppd/plugins/radius/radius.c 2013-01-15 22:25:13.485410720 +0100 >@@ -875,7 +875,7 @@ > u_char buf[16]; > > if (vp->lvalue != 32) { >- error("RADIUS: Incorrect attribute length (%d) for MS-CHAP-MPPE-Keys", >+ error("RADIUS radius_setmppekeys: Incorrect attribute length (%d) for MS-CHAP-MPPE-Keys", > vp->lvalue); > return -1; > } >@@ -933,12 +933,20 @@ > if (vp->attribute == PW_MS_MPPE_RECV_KEY) > type = "Recv"; > >- if (vp->lvalue != 34) { >- error("RADIUS: Incorrect attribute length (%d) for MS-MPPE-%s-Key", >+ if (vp->lvalue != 34 && vp->lvalue != 50) { >+ error("RADIUS radius_setmppekeys2: Incorrect attribute length (%d) for MS-MPPE-%s-Key", > vp->lvalue, type); > return -1; > } > >+ if (vp->lvalue == 50) { >+ memcpy(plain, strndup(vp->strvalue, sizeof(plain)), sizeof(plain)); >+ } >+ >+ if (vp->lvalue == 32) { >+ memcpy(plain, vp->strvalue, sizeof(plain)); >+ } >+ > if ((salt[0] & 0x80) == 0) { > error("RADIUS: Illegal salt value for MS-MPPE-%s-Key attribute", type); > return -1; > >--- ppp-2.4.5-orig/pppd/plugins/radius/radius.c 2013-01-15 22:21:41.518782305 +0100 >+++ ppp-2.4.5-new/pppd/plugins/radius/radius.c 2013-01-15 22:25:13.485410720 +0100 >@@ -963,12 +963,6 @@ > for (i = 0; i < 16; i++) > plain[i] ^= buf[i]; > >- if (plain[0] != sizeof(mppe_send_key) /* 16 */) { >- error("RADIUS: Incorrect key length (%d) for MS-MPPE-%s-Key attribute", >- (int) plain[0], type); >- return -1; >- } >- > MD5_Init(&Context); > MD5_Update(&Context, req_info->secret, strlen(req_info->secret)); > MD5_Update(&Context, crypt, 16); >--- ppp-2.4.5-orig/pppd/eap.c 2013-01-14 19:28:17.518782779 +0100 >+++ ppp-2.4.5-new/pppd/eap.c 2013-01-14 21:00:20.409658166 +0100 >@@ -1822,6 +1822,7 @@ > > switch (typenum) { > case EAPT_TLS: >+ case EAPT_PEAP: > case EAPT_TTLS: > /* use a Radius Server to authenticate this peer with EAP TLS */ > esp->es_server.ea_state = eapTLSAuth; >@@ -1873,6 +1872,7 @@ > > switch (vallen) { > case EAPT_TLS: >+ case EAPT_PEAP: > esp->es_server.ea_state = eapTLSAuth; > break; > >--- ppp-2.4.5-orig/pppd/eap.h 2013-01-14 19:28:17.518782779 +0100 >+++ ppp-2.4.5-new/pppd/eap.h 2013-01-14 20:59:41.801411378 +0100 >@@ -60,6 +60,7 @@ > #define EAPT_SRP 19 /* Secure Remote Password */ > /* 20 is deprecated */ > #define EAPT_TTLS 21 /* Tunnelles TLS */ >+#define EAPT_PEAP 25 /* Protected EAP */ > > /* EAP SRP-SHA1 Subtypes */ > #define EAPSRP_CHALLENGE 1 /* Request 1 - Challenge */ > >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 648217
:
678423
|
678433
|
678842
|
679094
| 718350