Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • smradius/smradius
  • centiva-shail/smradius
  • nkukard/smradius
3 results
Show changes
Showing
with 3614 additions and 1671 deletions
#
# Allegedly for ProFTPd.
#
# $Id: dictionary.unix,v 1.1 2006/11/14 17:44:59 lem Exp $
#
VENDOR Unix 4
ATTRIBUTE Unix-FTP-UID 10 integer Unix
ATTRIBUTE Unix-FTP-GID 11 integer Unix
ATTRIBUTE Unix-FTP-Home 12 string Unix
ATTRIBUTE Unix-FTP-Shell 13 string Unix
ATTRIBUTE Unix-FTP-Group-Names 14 string Unix
ATTRIBUTE Unix-FTP-Group-Ids 15 string Unix
#
# dictionary.usr USR Robotics dictionary.
#
# Taken from the dictionary included with the USR RADIUS server,
# and adjusted a bit.
#
# Version: $Id: dictionary.usr,v 1.1 2006/11/14 17:44:59 lem Exp $
#
#
# USR specific attributes
#
# Prompt value should be 1 for echo, 0 for no echo, default 1.
#ATTRIBUTE Prompt 64 integer
ATTRIBUTE Multi-Link-Flag 126 integer
ATTRIBUTE Char-Noecho 250 integer
#
# USR specific Integer Translations
#
VALUE Termination-Action Manage-Resources 2
VALUE Acct-Status-Type Modem-Start 4
VALUE Acct-Status-Type Modem-Stop 5
VALUE Acct-Status-Type Cancel 6
VALUE Multi-Link-Flag True 1
VALUE Multi-Link-Flag False 0
# USR specific Authentication Types
#
# These are commented out because the conflict with the standard
# definitions.
#
#VALUE Acct-Authentic None 0
#VALUE Acct-Authentic Remote 3
#VALUE Acct-Authentic RADIUS 4
#VALUE Acct-Authentic MNET 5
#VALUE Acct-Authentic KCHAP 6
#VALUE Acct-Authentic TACACS 7
#VALUE Acct-Authentic Realm 8
#VALUE Acct-Authentic Local 9
#VALUE Acct-Authentic File 10
#VALUE Acct-Authentic Local-VPN 11
#
# USR Extensions: USR Vendor-Specific stuff.
#
# For now in NMC format (whatever that stands for), though the
# normal vendor-specific format would work just as well.
#
#
VENDOR USR 429
ATTRIBUTE USR-Last-Number-Dialed-Out 0x0066 string USR
ATTRIBUTE USR-Last-Number-Dialed-In-DNIS 0x00E8 string USR
ATTRIBUTE USR-Last-Callers-Number-ANI 0x00E9 string USR
ATTRIBUTE USR-Channel 0xBF38 integer USR
ATTRIBUTE USR-Event-Id 0xBFBE integer USR
ATTRIBUTE USR-Event-Date-Time 0xBF2F date USR
ATTRIBUTE USR-Call-Start-Date-Time 0xBFF7 date USR
ATTRIBUTE USR-Call-End-Date-Time 0xBFF6 date USR
ATTRIBUTE USR-Default-DTE-Data-Rate 0x005E integer USR
ATTRIBUTE USR-Initial-Rx-Link-Data-Rate 0xBF2D integer USR
ATTRIBUTE USR-Final-Rx-Link-Data-Rate 0xBF2C integer USR
ATTRIBUTE USR-Initial-Tx-Link-Data-Rate 0x006A integer USR
ATTRIBUTE USR-Final-Tx-Link-Data-Rate 0x006B integer USR
ATTRIBUTE USR-Chassis-Temperature 0xBF31 integer USR
ATTRIBUTE USR-Chassis-Temp-Threshold 0xBE84 integer USR
ATTRIBUTE USR-Actual-Voltage 0xBF32 integer USR
ATTRIBUTE USR-Expected-Voltage 0xBF33 integer USR
ATTRIBUTE USR-Power-Supply-Number 0xBF34 integer USR
ATTRIBUTE USR-Card-Type 0xBE85 integer USR
ATTRIBUTE USR-Chassis-Slot 0xBF39 integer USR
ATTRIBUTE USR-Sync-Async-Mode 0x0067 integer USR
ATTRIBUTE USR-Originate-Answer-Mode 0x0068 integer USR
ATTRIBUTE USR-Modulation-Type 0x006C integer USR
ATTRIBUTE USR-Connect-Term-Reason 0x009B integer USR
ATTRIBUTE USR-Failure-to-Connect-Reason 0x0069 integer USR
ATTRIBUTE USR-Equalization-Type 0x006F integer USR
ATTRIBUTE USR-Fallback-Enabled 0x0070 integer USR
ATTRIBUTE USR-Connect-Time-Limit 0xBFE7 integer USR
ATTRIBUTE USR-Number-of-Rings-Limit 0xBFE6 integer USR
ATTRIBUTE USR-DTE-Data-Idle-Timout 0x0048 integer USR
ATTRIBUTE USR-Characters-Sent 0x0071 integer USR
ATTRIBUTE USR-Characters-Received 0x0072 integer USR
ATTRIBUTE USR-Blocks-Sent 0x0075 integer USR
ATTRIBUTE USR-Blocks-Received 0x0076 integer USR
ATTRIBUTE USR-Blocks-Resent 0x0077 integer USR
ATTRIBUTE USR-Retrains-Requested 0x0078 integer USR
ATTRIBUTE USR-Retrains-Granted 0x0079 integer USR
ATTRIBUTE USR-Line-Reversals 0x007A integer USR
ATTRIBUTE USR-Number-Of-Characters-Lost 0x007B integer USR
ATTRIBUTE USR-Number-of-Blers 0x007D integer USR
ATTRIBUTE USR-Number-of-Link-Timeouts 0x007E integer USR
ATTRIBUTE USR-Number-of-Fallbacks 0x007F integer USR
ATTRIBUTE USR-Number-of-Upshifts 0x0080 integer USR
ATTRIBUTE USR-Number-of-Link-NAKs 0x0081 integer USR
ATTRIBUTE USR-DTR-False-Timeout 0x00BE integer USR
ATTRIBUTE USR-Fallback-Limit 0x00BF integer USR
ATTRIBUTE USR-Block-Error-Count-Limit 0x00C0 integer USR
ATTRIBUTE USR-DTR-True-Timeout 0x00DA integer USR
ATTRIBUTE USR-Security-Login-Limit 0xBEDE integer USR
ATTRIBUTE USR-Security-Resp-Limit 0xBEFA integer USR
ATTRIBUTE USR-DTE-Ring-No-Answer-Limit 0xBF17 integer USR
ATTRIBUTE USR-Back-Channel-Data-Rate 0x007C integer USR
ATTRIBUTE USR-Simplified-MNP-Levels 0x0099 integer USR
ATTRIBUTE USR-Simplified-V42bis-Usage 0x00C7 integer USR
ATTRIBUTE USR-Mbi_Ct_PRI_Card_Slot 0x0184 integer USR
ATTRIBUTE USR-Mbi_Ct_TDM_Time_Slot 0x0185 integer USR
ATTRIBUTE USR-Mbi_Ct_PRI_Card_Span_Line 0x0186 integer USR
ATTRIBUTE USR-Mbi_Ct_BChannel_Used 0x0187 integer USR
ATTRIBUTE USR-Physical-State 0xBE77 integer USR
ATTRIBUTE USR-Packet-Bus-Session 0xBF14 integer USR
ATTRIBUTE USR-Server-Time 0xF000 date USR
# 0xBE5D-0xBE63 sent with Event-Id 79
ATTRIBUTE USR-Channel-Connected-To 0xBE5D integer USR
ATTRIBUTE USR-Slot-Connected-To 0xBE5E integer USR
ATTRIBUTE USR-Device-Connected-To 0xBE5F integer USR
ATTRIBUTE USR-NFAS-ID 0xBE60 integer USR
ATTRIBUTE USR-Q931-Call-Reference-Value 0xBE61 integer USR
ATTRIBUTE USR-Call-Event-Code 0xBE62 integer USR
ATTRIBUTE USR-DS0 0xBE63 integer USR
# DS0s sent with Event-Id 77,78
ATTRIBUTE USR-DS0s 0xBE64 string USR
# Gateway-IP-Address sent with Event-Id 71,72
ATTRIBUTE USR-Gateway-IP-Address 0xBE66 ipaddr USR
#
# These are CCA Radius attributes
#
ATTRIBUTE USR-PW_USR_IFilter_IP 0x9000 string USR
ATTRIBUTE USR-PW_USR_IFilter_IPX 0x9001 string USR
ATTRIBUTE USR-PW_USR_OFilter_IP 0x9003 string USR
ATTRIBUTE USR-PW_USR_OFilter_IPX 0x9004 string USR
ATTRIBUTE USR-PW_USR_OFilter_SAP 0x9005 string USR
ATTRIBUTE USR-PW_VPN_ID 0x9006 string USR
ATTRIBUTE USR-PW_VPN_Name 0x9007 string USR
ATTRIBUTE USR-PW_VPN_Neighbor 0x9008 ipaddr USR
ATTRIBUTE USR-PW_Framed_Routing_V2 0x9009 string USR
ATTRIBUTE USR-PW_VPN_Gateway 0x900a string USR
ATTRIBUTE USR-PW_Tunnel_Authentication 0x900b string USR
ATTRIBUTE USR-PW_Index 0x900c string USR
ATTRIBUTE USR-PW_Cutoff 0x900d string USR
ATTRIBUTE USR-PW_Packet 0x900e string USR
ATTRIBUTE USR-Primary_DNS_Server 0x900f ipaddr USR
ATTRIBUTE USR-Secondary_DNS_Server 0x9010 ipaddr USR
ATTRIBUTE USR-Primary_NBNS_Server 0x9011 ipaddr USR
ATTRIBUTE USR-Secondary_NBNS_Server 0x9012 ipaddr USR
ATTRIBUTE USR-Syslog-Tap 0x9013 integer USR
ATTRIBUTE USR-Chassis-Call-Slot 0x9019 integer USR
ATTRIBUTE USR-Chassis-Call-Span 0x901A integer USR
ATTRIBUTE USR-Chassis-Call-Channel 0x901B integer USR
ATTRIBUTE USR-Keypress-Timeout 0x901C integer USR
ATTRIBUTE USR-Unauthenticated-Time 0x901D integer USR
ATTRIBUTE USR-Connect-Speed 0x9023 integer USR
ATTRIBUTE USR-Framed_IP_Address_Pool_Name 0x9024 string USR
ATTRIBUTE USR-MP-EDO 0x9025 string USR
#
# Pilgrim attributes
#
ATTRIBUTE USR-Bearer-Capabilities 0x9800 integer USR
ATTRIBUTE USR-Speed-Of-Connection 0x9801 integer USR
ATTRIBUTE USR-Max-Channels 0x9802 integer USR
ATTRIBUTE USR-Channel-Expansion 0x9803 integer USR
ATTRIBUTE USR-Channel-Decrement 0x9804 integer USR
ATTRIBUTE USR-Expansion-Algorithm 0x9805 integer USR
ATTRIBUTE USR-Compression-Algorithm 0x9806 integer USR
ATTRIBUTE USR-Receive-Acc-Map 0x9807 integer USR
ATTRIBUTE USR-Transmit-Acc-Map 0x9808 integer USR
ATTRIBUTE USR-Compression-Reset-Mode 0x980a integer USR
ATTRIBUTE USR-Min-Compression-Size 0x980b integer USR
ATTRIBUTE USR-IP 0x980c integer USR
ATTRIBUTE USR-IPX 0x980d integer USR
ATTRIBUTE USR-Filter-Zones 0x980e integer USR
ATTRIBUTE USR-Appletalk 0x980f integer USR
ATTRIBUTE USR-Bridging 0x9810 integer USR
ATTRIBUTE USR-Spoofing 0x9811 integer USR
ATTRIBUTE USR-Host-Type 0x9812 integer USR
ATTRIBUTE USR-Send-Name 0x9813 string USR
ATTRIBUTE USR-Send-Password 0x9814 string USR
ATTRIBUTE USR-Start-Time 0x9815 integer USR
ATTRIBUTE USR-End-Time 0x9816 integer USR
ATTRIBUTE USR-Send-Script1 0x9817 string USR
ATTRIBUTE USR-Reply-Script1 0x9818 string USR
ATTRIBUTE USR-Send-Script2 0x9819 string USR
ATTRIBUTE USR-Reply-Script2 0x981a string USR
ATTRIBUTE USR-Send-Script3 0x981b string USR
ATTRIBUTE USR-Reply-Script3 0x981c string USR
ATTRIBUTE USR-Send-Script4 0x981d string USR
ATTRIBUTE USR-Reply-Script4 0x981e string USR
ATTRIBUTE USR-Send-Script5 0x981f string USR
ATTRIBUTE USR-Reply-Script5 0x9820 string USR
ATTRIBUTE USR-Send-Script6 0x9821 string USR
ATTRIBUTE USR-Reply-Script6 0x9822 string USR
ATTRIBUTE USR-Terminal-Type 0x9823 string USR
ATTRIBUTE USR-Appletalk-Network-Range 0x9824 integer USR
ATTRIBUTE USR-Local-IP-Address 0x9825 string USR
ATTRIBUTE USR-Routing-Protocol 0x9826 integer USR
ATTRIBUTE USR-Modem-Group 0x9827 integer USR
ATTRIBUTE USR-Modem-Training-Time 0x9842 integer USR
ATTRIBUTE USR-Interface-Index 0x9843 integer USR
ATTRIBUTE USR-MP-MRRU 0x982f integer USR
ATTRIBUTE USR-SAP-Filter-In 0x9002 string USR
ATTRIBUTE USR-MIC 0x9014 string USR
ATTRIBUTE USR-Log-Filter-Packets 0x9017 string USR
ATTRIBUTE USR-VPN-Encrypter 0x901e integer USR
ATTRIBUTE USR-Re-Chap-Timeout 0x9020 integer USR
ATTRIBUTE USR-Tunnel-Switch-Endpoint 0x9868 string USR
ATTRIBUTE USR-IP-SAA-Filter 0x9870 integer USR
ATTRIBUTE Initial-Modulation-Type 0x0923 integer USR
ATTRIBUTE USR-VTS-Session-Key 0x9856 string USR
ATTRIBUTE USR-Orig-NAS-Type 0x9857 string USR
ATTRIBUTE USR-Call-Arrival-Time 0x9858 integer USR
ATTRIBUTE USR-Call-End-Time 0x9859 integer USR
ATTRIBUTE USR-Tunnel-Auth-Hostname 0x986b string USR
ATTRIBUTE USR-Acct-Reason-Code 0x986c integer USR
ATTRIBUTE USR-Supports-Tags 0x9889 integer USR
ATTRIBUTE USR-HARC-Disconnect-Code 0x988b integer USR
ATTRIBUTE USR-RMMIE-Status 0x01cd integer USR
ATTRIBUTE USR-RMMIE-Last-Update-Event 0x0901 integer USR
ATTRIBUTE USR-RMMIE-x2-Status 0x0909 integer USR
ATTRIBUTE USR-RMMIE-Planned-Disconnect 0x090a integer USR
ATTRIBUTE USR-VPN-GW-Location-Id 0x901f string USR
ATTRIBUTE USR-CCP-Algorithm 0x9021 integer USR
ATTRIBUTE USR-ACCM-Type 0x9022 integer USR
ATTRIBUTE USR-Local-Framed-IP-Addr 0x9026 ipaddr USR
ATTRIBUTE USR-IPX-Routing 0x9828 integer USR
ATTRIBUTE USR-IPX-WAN 0x9829 integer USR
ATTRIBUTE USR-IP-RIP-Policies 0x982a integer USR
ATTRIBUTE USR-IP-RIP-Simple-Auth-Password 0x982b string USR
ATTRIBUTE USR-IP-RIP-Input-Filter 0x982c string USR
ATTRIBUTE USR-IP-Call-Input-Filter 0x982d string USR
ATTRIBUTE USR-IPX-RIP-Input-Filter 0x982e string USR
ATTRIBUTE USR-IPX-Call-Input-Filter 0x9830 string USR
ATTRIBUTE USR-AT-Input-Filter 0x9831 string USR
ATTRIBUTE USR-AT-RTMP-Input-Filter 0x9832 string USR
ATTRIBUTE USR-AT-Zip-Input-Filter 0x9833 string USR
ATTRIBUTE USR-AT-Call-Input-Filter 0x9834 string USR
ATTRIBUTE USR-ET-Bridge-Input-Filter 0x9835 string USR
ATTRIBUTE USR-IP-RIP-Output-Filter 0x9836 string USR
ATTRIBUTE USR-IP-Call-Output-Filter 0x9837 string USR
ATTRIBUTE USR-IPX-RIP-Output-Filter 0x9838 string USR
ATTRIBUTE USR-IPX-Call-Output-Filter 0x9839 string USR
ATTRIBUTE USR-AT-Output-Filter 0x983a string USR
ATTRIBUTE USR-AT-RTMP-Output-Filter 0x983b string USR
ATTRIBUTE USR-AT-Zip-Output-Filter 0x983c string USR
ATTRIBUTE USR-AT-Call-Output-Filter 0x983d string USR
ATTRIBUTE USR-ET-Bridge-Output-Filter 0x983e string USR
# This item name is too long for the server to parse; had to chop the r off. FIXME?
ATTRIBUTE USR-ET-Bridge-Call-Output-Filte 0x983f string USR
ATTRIBUTE USR-IP-Default-Route-Option 0x9840 integer USR
ATTRIBUTE USR-MP-EDO-HIPER 0x9841 string USR
ATTRIBUTE USR-Tunnel-Security 0x9844 integer USR
ATTRIBUTE USR-Port-Tap 0x9845 integer USR
ATTRIBUTE USR-Port-Tap-Format 0x9846 integer USR
ATTRIBUTE USR-Port-Tap-Output 0x9847 integer USR
ATTRIBUTE USR-Port-Tap-Facility 0x9848 integer USR
ATTRIBUTE USR-Port-Tap-Priority 0x9849 integer USR
ATTRIBUTE USR-Port-Tap-Address 0x984a ipaddr USR
ATTRIBUTE USR-MobileIP-Home-Agent-Address 0x984b ipaddr USR
ATTRIBUTE USR-Tunneled-MLPP 0x984c integer USR
ATTRIBUTE USR-Multicast-Proxy 0x984d integer USR
ATTRIBUTE USR-Multicast-Receive 0x984e integer USR
ATTRIBUTE USR-Multicast-Forwarding 0x9850 integer USR
ATTRIBUTE USR-IGMP-Query-Interval 0x9851 integer USR
ATTRIBUTE USR-IGMP-Maximum-Response-Time 0x9852 integer USR
ATTRIBUTE USR-IGMP-Robustness 0x9853 integer USR
ATTRIBUTE USR-IGMP-Version 0x9854 integer USR
ATTRIBUTE USR-Callback-Type 0x986a integer USR
ATTRIBUTE USR-Request-Type 0xf001 integer USR
ATTRIBUTE USR-RMMIE-Num-Of-Updates 0x01ce integer USR
ATTRIBUTE USR-RMMIE-Manufacturer-ID 0x01df integer USR
ATTRIBUTE USR-RMMIE-Product-Code 0x01e0 string USR
ATTRIBUTE USR-RMMIE-Serial-Number 0x01e1 string USR
ATTRIBUTE USR-RMMIE-Firmware-Version 0x01e2 string USR
ATTRIBUTE USR-RMMIE-Firmware-Build-Date 0x01e3 string USR
ATTRIBUTE USR-Call-Arrival-in-GMT 0xbe52 date USR
ATTRIBUTE USR-Call-Connect-in-GMT 0xbe51 date USR
ATTRIBUTE USR-Call-Terminate-in-GMT 0xbe50 date USR
ATTRIBUTE USR-IDS0-Call-Type 0xbe4f integer USR
ATTRIBUTE USR-Call-Reference-Number 0xbe7d integer USR
ATTRIBUTE USR-CDMA-Call-Reference-Number 0x0183 integer USR
ATTRIBUTE USR-Mobile-IP-Address 0x088e ipaddr USR
ATTRIBUTE USR-IWF-IP-Address 0x03f4 ipaddr USR
ATTRIBUTE USR-Called-Party-Number 0x0890 string USR
ATTRIBUTE USR-Calling-Party-Number 0x088f string USR
ATTRIBUTE USR-Call-Type 0x0891 integer USR
ATTRIBUTE USR-ESN 0x0892 string USR
ATTRIBUTE USR-IWF-Call-Identifier 0x0893 integer USR
ATTRIBUTE USR-IMSI 0x0894 string USR
ATTRIBUTE USR-Service-Option 0x0895 integer USR
ATTRIBUTE USR-Disconnect-Cause-Indicator 0x0896 integer USR
ATTRIBUTE USR-Mobile-NumBytes-Txed 0x0897 integer USR
ATTRIBUTE USR-Mobile-NumBytes-Rxed 0x0898 integer USR
ATTRIBUTE USR-Num-Fax-Pages-Processed 0x0899 integer USR
ATTRIBUTE USR-Compression-Type 0x089a integer USR
ATTRIBUTE USR-Call-Error-Code 0x089b integer USR
ATTRIBUTE USR-Modem-Setup-Time 0x089c integer USR
ATTRIBUTE USR-Call-Connecting-Time 0x089d integer USR
ATTRIBUTE USR-Connect-Time 0x089e integer USR
ATTRIBUTE USR-RMMIE-Last-Update-Time 0x0900 integer USR
ATTRIBUTE USR-RMMIE-Rcv-Tot-PwrLvl 0x0902 integer USR
ATTRIBUTE USR-RMMIE-Rcv-PwrLvl-3300Hz 0x0903 integer USR
ATTRIBUTE USR-RMMIE-Rcv-PwrLvl-3750Hz 0x0904 integer USR
ATTRIBUTE USR-RMMIE-PwrLvl-NearEcho-Canc 0x0905 integer USR
ATTRIBUTE USR-RMMIE-PwrLvl-FarEcho-Canc 0x0906 integer USR
ATTRIBUTE USR-RMMIE-PwrLvl-Noise-Lvl 0x0907 integer USR
ATTRIBUTE USR-RMMIE-PwrLvl-Xmit-Lvl 0x0908 integer USR
ATTRIBUTE USR-Framed-IPX-Route 0x9027 ipaddr USR
ATTRIBUTE USR-MPIP-Tunnel-Originator 0x9028 ipaddr USR
ATTRIBUTE USR-IGMP-Routing 0x9855 integer USR
ATTRIBUTE USR-Rad-Multicast-Routing-Ttl 0x9860 integer USR
# again, too long for cistron to parse "rate-limit", "protocol" and "boundary"
ATTRIBUTE USR-Rad-Multicast-Routing-RtLim 0x9861 integer USR
ATTRIBUTE USR-Rad-Multicast-Routing-Proto 0x9862 integer USR
ATTRIBUTE USR-Rad-Multicast-Routing-Bound 0x9863 string USR
ATTRIBUTE USR-Rad-Dvmrp-Metric 0x9864 integer USR
ATTRIBUTE USR-Chat-Script-Name 0x9865 string USR
ATTRIBUTE USR-CUSR-hat-Script-Rules 0x9866 string USR
ATTRIBUTE USR-Rad-Location-Type 0x9867 integer USR
ATTRIBUTE USR-OSPF-Addressless-Index 0x9869 integer USR
ATTRIBUTE USR-DNIS-ReAuthentication 0x9875 integer USR
ATTRIBUTE USR-NAS-Type 0xf002 integer USR
ATTRIBUTE USR-Auth-Mode 0xf003 integer USR
#
# Integer Translations
#
#VALUE USR-Character-Echo Echo-On 0
#VALUE USR-Character-Echo Echo-Off 1
VALUE USR-PW_Framed_Routing_V2 Off 0
VALUE USR-PW_Framed_Routing_V2 On 1
VALUE USR-Syslog-Tap Off 0
VALUE USR-Syslog-Tap On-Raw 1
VALUE USR-Syslog-Tap On-Framed 2
VALUE USR-Syslog-Tap Unknown 4294967295
# Event Indentifiers
VALUE USR-Event-Id Module-Inserted 6
VALUE USR-Event-Id Module-Removed 7
VALUE USR-Event-Id PSU-Voltage-Alarm 8
VALUE USR-Event-Id PSU-Failed 9
VALUE USR-Event-Id HUB-Temp-Out-of-Range 10
VALUE USR-Event-Id Fan-Failed 11
VALUE USR-Event-Id Watchdog-Timeout 12
VALUE USR-Event-Id Mgmt-Bus-Failure 13
VALUE USR-Event-Id In-Connection-Est 14
VALUE USR-Event-Id Out-Connection-Est 15
VALUE USR-Event-Id In-Connection-Term 16
VALUE USR-Event-Id Out-Connection-Term 17
VALUE USR-Event-Id Connection-Failed 18
VALUE USR-Event-Id Connection-Timeout 19
VALUE USR-Event-Id DTE-Transmit-Idle 20
VALUE USR-Event-Id DTR-True 21
VALUE USR-Event-Id DTR-False 22
VALUE USR-Event-Id Block-Error-at-Threshold 23
VALUE USR-Event-Id Fallbacks-at-Threshold 24
VALUE USR-Event-Id No-Dial-Tone-Detected 25
VALUE USR-Event-Id No-Loop-Current-Detected 26
VALUE USR-Event-Id Yellow-Alarm 27
VALUE USR-Event-Id Red-Alarm 28
VALUE USR-Event-Id Loss-Of-Signal 29
VALUE USR-Event-Id Rcv-Alrm-Ind-Signal 30
VALUE USR-Event-Id Timing-Source-Switch 31
VALUE USR-Event-Id Modem-Reset-by-DTE 32
VALUE USR-Event-Id Modem-Ring-No-Answer 33
VALUE USR-Event-Id DTE-Ring-No-Answer 34
VALUE USR-Event-Id Pkt-Bus-Session-Active 35
VALUE USR-Event-Id Pkt-Bus-Session-Congestion 36
VALUE USR-Event-Id Pkt-Bus-Session-Lost 37
VALUE USR-Event-Id Pkt-Bus-Session-Inactive 38
VALUE USR-Event-Id User-Interface-Reset 39
VALUE USR-Event-Id Gateway-Port-Out-of-Service 40
VALUE USR-Event-Id Gateway-Port-Link-Active 41
VALUE USR-Event-Id Dial-Out-Login-Failure 42
VALUE USR-Event-Id Dial-In-Login-Failure 43
VALUE USR-Event-Id Dial-Out-Restricted-Number 44
VALUE USR-Event-Id Dial-Back-Restricted-Number 45
VALUE USR-Event-Id User-Blacklisted 46
VALUE USR-Event-Id Attempted-Login-Blacklisted 47
VALUE USR-Event-Id Response-Attempt-Limit-Exceeded 48
VALUE USR-Event-Id Login-Attempt-Limit-Exceeded 49
VALUE USR-Event-Id Dial-Out-Call-Duration 50
VALUE USR-Event-Id Dial-In-Call-Duration 51
VALUE USR-Event-Id Pkt-Bus-Session-Err-Status 52
VALUE USR-Event-Id NMC-AutoRespnse-Trap 53
VALUE USR-Event-Id Acct-Server-Contact-Loss 54
VALUE USR-Event-Id Yellow-Alarm-Clear 55
VALUE USR-Event-Id Red-Alarm-Clear 56
VALUE USR-Event-Id Loss-Of-Signal-Clear 57
VALUE USR-Event-Id Rcv-Alrm-Ind-Signal-Clear 58
VALUE USR-Event-Id Incoming-Connection-Established 59
VALUE USR-Event-Id Outgoing-Connection-Established 60
VALUE USR-Event-Id Incoming-Connection-Terminated 61
VALUE USR-Event-Id Outgoing-Connection-Terminated 62
VALUE USR-Event-Id Connection-Attempt-Failure 63
VALUE USR-Event-Id Continuous-CRC-Alarm 64
VALUE USR-Event-Id Continuous-CRC-Alarm-Clear 65
VALUE USR-Event-Id Physical-State-Change 66
VALUE USR-Event-Id Gateway-Network-Failed 71
VALUE USR-Event-Id Gateway-Network-Restored 72
VALUE USR-Event-Id Packet-Bus-Clock-Lost 73
VALUE USR-Event-Id Packet-Bus-Clock-Restored 74
VALUE USR-Event-Id D-Channel-In-Service 75
VALUE USR-Event-Id D-Channel-Out-of-Service 76
VALUE USR-Event-Id DS0s-In-Service 77
VALUE USR-Event-Id DS0s-Out-of-Service 78
VALUE USR-Event-Id T1/T1PRI/E1PRI-Call-Event 79
VALUE USR-Event-Id Psu-Incompatible 80
VALUE USR-Event-Id T1,T1-E1/PRI-Call-Arrive-Event 81
VALUE USR-Event-Id T1,T1-E1/PRI-Call-Connect-Event 82
VALUE USR-Event-Id T1,T1-E1/PRI-Call-Termina-Event 83
VALUE USR-Event-Id T1,T1-E1/PRI-Call-Failed-Event 84
VALUE USR-Event-Id DNS-Contact-Lost 85
VALUE USR-Event-Id NTP-Contact-Lost 86
VALUE USR-Event-Id NTP-Contact-Restored 87
VALUE USR-Event-Id IPGW-Link-Up 88
VALUE USR-Event-Id IPGW-Link-Down 89
VALUE USR-Event-Id NTP-Contact-Degraded 90
VALUE USR-Event-Id In-Connection-Failed 91
VALUE USR-Event-Id Out-Connection-Failed 92
VALUE USR-Event-Id Application-ProcessorReset 93
VALUE USR-Event-Id DSP-Reset 94
VALUE USR-Event-Id Changed-to-Maint-Srvs-State 95
VALUE USR-Event-Id Loop-Back-cleared-on-channel 96
VALUE USR-Event-Id Loop-Back-on-channel 97
VALUE USR-Event-Id Telco-Abnormal-Response 98
VALUE USR-Event-Id DNS-Contact-Restored 99
VALUE USR-Event-Id DNS-Contact-Degraded 100
VALUE USR-Event-Id RADIUS-Accounting-Restored 101
VALUE USR-Event-Id RADIUS-Accounting-Group-Restore 102
VALUE USR-Event-Id RADIUS-Accounting-Group-Degrade 103
VALUE USR-Event-Id RADIUS-Accounting-Group-NonOper 104
VALUE USR-Event-Id T1/T1-E1/PRI-InCall-Fail-Event 119
VALUE USR-Event-Id T1/T1-E1/PRI-OutCall-Fail-Event 120
VALUE USR-Event-Id RMMIE-Retrain-Event 121
VALUE USR-Event-Id RMMIE-Speed-Shift-Event 122
VALUE USR-Event-Id CDMA-Call-Start 191
VALUE USR-Event-Id CDMA-Call-End 192
VALUE USR-Card-Type SlotEmpty 1
VALUE USR-Card-Type SlotUnknown 2
VALUE USR-Card-Type NetwMgtCard 3
VALUE USR-Card-Type DualT1NAC 4
VALUE USR-Card-Type DualModemNAC 5
VALUE USR-Card-Type QuadModemNAC 6
VALUE USR-Card-Type TrGatewayNAC 7
VALUE USR-Card-Type X25GatewayNAC 8
VALUE USR-Card-Type DualV34ModemNAC 9
VALUE USR-Card-Type QuadV32DigitalModemNAC 10
VALUE USR-Card-Type QuadV32AnalogModemNAC 11
VALUE USR-Card-Type QuadV32DigAnlModemNAC 12
VALUE USR-Card-Type QuadV34DigModemNAC 13
VALUE USR-Card-Type QuadV34AnlModemNAC 14
VALUE USR-Card-Type QuadV34DigAnlModemNAC 15
VALUE USR-Card-Type SingleT1NAC 16
VALUE USR-Card-Type EthernetGatewayNAC 17
VALUE USR-Card-Type AccessServer 18
VALUE USR-Card-Type 486TrGatewayNAC 19
VALUE USR-Card-Type 486EthernetGatewayNAC 20
VALUE USR-Card-Type DualRS232NAC 22
VALUE USR-Card-Type 486X25GatewayNAC 23
VALUE USR-Card-Type ApplicationServerNAC 25
VALUE USR-Card-Type ISDNGatewayNAC 26
VALUE USR-Card-Type ISDNpriT1NAC 27
VALUE USR-Card-Type ClkedNetMgtCard 28
VALUE USR-Card-Type ModemPoolManagementNAC 29
VALUE USR-Card-Type ModemPoolNetserverNAC 30
VALUE USR-Card-Type ModemPoolV34ModemNAC 31
VALUE USR-Card-Type ModemPoolISDNNAC 32
VALUE USR-Card-Type NTServerNAC 33
VALUE USR-Card-Type QuadV34DigitalG2NAC 34
VALUE USR-Card-Type QuadV34AnalogG2NAC 35
VALUE USR-Card-Type QuadV34DigAnlgG2NAC 36
VALUE USR-Card-Type NETServerFrameRelayNAC 37
VALUE USR-Card-Type NETServerTokenRingNAC 38
VALUE USR-Card-Type X2524ChannelNAC 39
VALUE USR-Card-Type WirelessGatewayNac 42
VALUE USR-Card-Type EnhancedAccessServer 44
VALUE USR-Card-Type EnhancedISDNGatewayNAC 45
VALUE USR-Card-Type DualT1NIC 1001
VALUE USR-Card-Type DualAlogMdmNIC 1002
VALUE USR-Card-Type QuadDgtlMdmNIC 1003
VALUE USR-Card-Type QuadAlogDgtlMdmNIC 1004
VALUE USR-Card-Type TokenRingNIC 1005
VALUE USR-Card-Type SingleT1NIC 1006
VALUE USR-Card-Type EthernetNIC 1007
VALUE USR-Card-Type ShortHaulDualT1NIC 1008
VALUE USR-Card-Type DualAlogMgdIntlMdmNIC 1009
VALUE USR-Card-Type X25NIC 1010
VALUE USR-Card-Type QuadAlogNonMgdMdmNIC 1011
VALUE USR-Card-Type QuadAlogMgdIntlMdmNIC 1012
VALUE USR-Card-Type QuadAlogNonMgdIntlMdmNIC 1013
VALUE USR-Card-Type QuadLsdLiMgdMdmNIC 1014
VALUE USR-Card-Type QuadLsdLiNonMgdMdmNIC 1015
VALUE USR-Card-Type QuadLsdLiMgdIntlMdmNIC 1016
VALUE USR-Card-Type QuadLsdLiNonMgdIntlMdmNIC 1017
VALUE USR-Card-Type HSEthernetWithV35NIC 1018
VALUE USR-Card-Type HSEthernetWithoutV35NIC 1019
VALUE USR-Card-Type DualHighSpeedV35NIC 1020
VALUE USR-Card-Type QuadV35RS232LowSpeedNIC 1021
VALUE USR-Card-Type DualE1NIC 1022
VALUE USR-Card-Type ShortHaulDualE1NIC 1023
VALUE USR-Card-Type BellcoreLongHaulDualT1NIC 1025
VALUE USR-Card-Type BellcoreShrtHaulDualT1NIC 1026
VALUE USR-Card-Type SCSIEdgeServerNIC 1027
VALUE USR-Default-DTE-Data-Rate 110-BPS 1
VALUE USR-Default-DTE-Data-Rate 300-BPS 2
VALUE USR-Default-DTE-Data-Rate 600-BPS 3
VALUE USR-Default-DTE-Data-Rate 1200-BPS 4
VALUE USR-Default-DTE-Data-Rate 2400-BPS 5
VALUE USR-Default-DTE-Data-Rate 4800-BPS 6
VALUE USR-Default-DTE-Data-Rate 7200-BPS 7
VALUE USR-Default-DTE-Data-Rate 9600-BPS 8
VALUE USR-Default-DTE-Data-Rate 12K-BPS 9
VALUE USR-Default-DTE-Data-Rate 14.4K-BPS 10
VALUE USR-Default-DTE-Data-Rate 16.8-BPS 11
VALUE USR-Default-DTE-Data-Rate 19.2K-BPS 12
VALUE USR-Default-DTE-Data-Rate 38.4K-BPS 13
VALUE USR-Default-DTE-Data-Rate 75-BPS 14
VALUE USR-Default-DTE-Data-Rate 450-BPS 15
VALUE USR-Default-DTE-Data-Rate UNKNOWN-BPS 16
VALUE USR-Default-DTE-Data-Rate 57.6K-BPS 17
VALUE USR-Default-DTE-Data-Rate 21.6K-BPS 18
VALUE USR-Default-DTE-Data-Rate 24K-BPS 19
VALUE USR-Default-DTE-Data-Rate 26K-BPS 20
VALUE USR-Default-DTE-Data-Rate 28K-BPS 21
VALUE USR-Default-DTE-Data-Rate 115K-BPS 22
VALUE USR-Initial-Rx-Link-Data-Rate 110-BPS 1
VALUE USR-Initial-Rx-Link-Data-Rate 300-BPS 2
VALUE USR-Initial-Rx-Link-Data-Rate 600-BPS 3
VALUE USR-Initial-Rx-Link-Data-Rate 1200-BPS 4
VALUE USR-Initial-Rx-Link-Data-Rate 2400-BPS 5
VALUE USR-Initial-Rx-Link-Data-Rate 4800-BPS 6
VALUE USR-Initial-Rx-Link-Data-Rate 7200-BPS 7
VALUE USR-Initial-Rx-Link-Data-Rate 9600-BPS 8
VALUE USR-Initial-Rx-Link-Data-Rate 12000-BPS 9
VALUE USR-Initial-Rx-Link-Data-Rate 14400-BPS 10
VALUE USR-Initial-Rx-Link-Data-Rate 16800-BPS 11
VALUE USR-Initial-Rx-Link-Data-Rate 19200-BPS 12
VALUE USR-Initial-Rx-Link-Data-Rate 38400-BPS 13
VALUE USR-Initial-Rx-Link-Data-Rate 75-BPS 14
VALUE USR-Initial-Rx-Link-Data-Rate 450-BPS 15
VALUE USR-Initial-Rx-Link-Data-Rate UNKNOWN-BPS 16
VALUE USR-Initial-Rx-Link-Data-Rate 57600-BPS 17
VALUE USR-Initial-Rx-Link-Data-Rate 21600-BPS 18
VALUE USR-Initial-Rx-Link-Data-Rate 24000-BPS 19
VALUE USR-Initial-Rx-Link-Data-Rate 26400-BPS 20
VALUE USR-Initial-Rx-Link-Data-Rate 28800-BPS 21
VALUE USR-Initial-Rx-Link-Data-Rate 115200-BPS 22
VALUE USR-Initial-Rx-Link-Data-Rate 31200-BPS 23
VALUE USR-Initial-Rx-Link-Data-Rate 33600-BPS 24
VALUE USR-Initial-Rx-Link-Data-Rate 25333-BPS 25
VALUE USR-Initial-Rx-Link-Data-Rate 26666-BPS 26
VALUE USR-Initial-Rx-Link-Data-Rate 28000-BPS 27
VALUE USR-Initial-Rx-Link-Data-Rate 29333-BPS 28
VALUE USR-Initial-Rx-Link-Data-Rate 30666-BPS 29
VALUE USR-Initial-Rx-Link-Data-Rate 32000-BPS 30
VALUE USR-Initial-Rx-Link-Data-Rate 33333-BPS 31
VALUE USR-Initial-Rx-Link-Data-Rate 34666-BPS 32
VALUE USR-Initial-Rx-Link-Data-Rate 36000-BPS 33
VALUE USR-Initial-Rx-Link-Data-Rate 37333-BPS 34
VALUE USR-Initial-Rx-Link-Data-Rate 38666-BPS 35
VALUE USR-Initial-Rx-Link-Data-Rate 40000-BPS 36
VALUE USR-Initial-Rx-Link-Data-Rate 41333-BPS 37
VALUE USR-Initial-Rx-Link-Data-Rate 42666-BPS 38
VALUE USR-Initial-Rx-Link-Data-Rate 44000-BPS 39
VALUE USR-Initial-Rx-Link-Data-Rate 45333-BPS 40
VALUE USR-Initial-Rx-Link-Data-Rate 46666-BPS 41
VALUE USR-Initial-Rx-Link-Data-Rate 48000-BPS 42
VALUE USR-Initial-Rx-Link-Data-Rate 49333-BPS 43
VALUE USR-Initial-Rx-Link-Data-Rate 50666-BPS 44
VALUE USR-Initial-Rx-Link-Data-Rate 52000-BPS 45
VALUE USR-Initial-Rx-Link-Data-Rate 53333-BPS 46
VALUE USR-Initial-Rx-Link-Data-Rate 54666-BPS 47
VALUE USR-Initial-Rx-Link-Data-Rate 56000-BPS 48
VALUE USR-Initial-Rx-Link-Data-Rate 57333-BPS 49
VALUE USR-Initial-Rx-Link-Data-Rate 58666-BPS 50
VALUE USR-Initial-Rx-Link-Data-Rate 60000-BPS 51
VALUE USR-Initial-Rx-Link-Data-Rate 61333-BPS 52
VALUE USR-Initial-Rx-Link-Data-Rate 62666-BPS 53
VALUE USR-Initial-Rx-Link-Data-Rate 64000-BPS 54
VALUE USR-Final-Rx-Link-Data-Rate 110-BPS 1
VALUE USR-Final-Rx-Link-Data-Rate 300-BPS 2
VALUE USR-Final-Rx-Link-Data-Rate 600-BPS 3
VALUE USR-Final-Rx-Link-Data-Rate 1200-BPS 4
VALUE USR-Final-Rx-Link-Data-Rate 2400-BPS 5
VALUE USR-Final-Rx-Link-Data-Rate 4800-BPS 6
VALUE USR-Final-Rx-Link-Data-Rate 7200-BPS 7
VALUE USR-Final-Rx-Link-Data-Rate 9600-BPS 8
VALUE USR-Final-Rx-Link-Data-Rate 12000-BPS 9
VALUE USR-Final-Rx-Link-Data-Rate 14400-BPS 10
VALUE USR-Final-Rx-Link-Data-Rate 16800-BPS 11
VALUE USR-Final-Rx-Link-Data-Rate 19200-BPS 12
VALUE USR-Final-Rx-Link-Data-Rate 38400-BPS 13
VALUE USR-Final-Rx-Link-Data-Rate 75-BPS 14
VALUE USR-Final-Rx-Link-Data-Rate 450-BPS 15
VALUE USR-Final-Rx-Link-Data-Rate UNKNOWN-BPS 16
VALUE USR-Final-Rx-Link-Data-Rate 57600-BPS 17
VALUE USR-Final-Rx-Link-Data-Rate 21600-BPS 18
VALUE USR-Final-Rx-Link-Data-Rate 24000-BPS 19
VALUE USR-Final-Rx-Link-Data-Rate 26400-BPS 20
VALUE USR-Final-Rx-Link-Data-Rate 28800-BPS 21
VALUE USR-Final-Rx-Link-Data-Rate 115200-BPS 22
VALUE USR-Final-Rx-Link-Data-Rate 31200-BPS 23
VALUE USR-Final-Rx-Link-Data-Rate 33600-BPS 24
VALUE USR-Final-Rx-Link-Data-Rate 25333-BPS 25
VALUE USR-Final-Rx-Link-Data-Rate 26666-BPS 26
VALUE USR-Final-Rx-Link-Data-Rate 28000-BPS 27
VALUE USR-Final-Rx-Link-Data-Rate 29333-BPS 28
VALUE USR-Final-Rx-Link-Data-Rate 30666-BPS 29
VALUE USR-Final-Rx-Link-Data-Rate 32000-BPS 30
VALUE USR-Final-Rx-Link-Data-Rate 33333-BPS 31
VALUE USR-Final-Rx-Link-Data-Rate 34666-BPS 32
VALUE USR-Final-Rx-Link-Data-Rate 36000-BPS 33
VALUE USR-Final-Rx-Link-Data-Rate 37333-BPS 34
VALUE USR-Final-Rx-Link-Data-Rate 38666-BPS 35
VALUE USR-Final-Rx-Link-Data-Rate 40000-BPS 36
VALUE USR-Final-Rx-Link-Data-Rate 41333-BPS 37
VALUE USR-Final-Rx-Link-Data-Rate 42666-BPS 38
VALUE USR-Final-Rx-Link-Data-Rate 44000-BPS 39
VALUE USR-Final-Rx-Link-Data-Rate 45333-BPS 40
VALUE USR-Final-Rx-Link-Data-Rate 46666-BPS 41
VALUE USR-Final-Rx-Link-Data-Rate 48000-BPS 42
VALUE USR-Final-Rx-Link-Data-Rate 49333-BPS 43
VALUE USR-Final-Rx-Link-Data-Rate 50666-BPS 44
VALUE USR-Final-Rx-Link-Data-Rate 52000-BPS 45
VALUE USR-Final-Rx-Link-Data-Rate 53333-BPS 46
VALUE USR-Final-Rx-Link-Data-Rate 54666-BPS 47
VALUE USR-Final-Rx-Link-Data-Rate 56000-BPS 48
VALUE USR-Final-Rx-Link-Data-Rate 57333-BPS 49
VALUE USR-Final-Rx-Link-Data-Rate 58666-BPS 50
VALUE USR-Final-Rx-Link-Data-Rate 60000-BPS 51
VALUE USR-Final-Rx-Link-Data-Rate 61333-BPS 52
VALUE USR-Final-Rx-Link-Data-Rate 62666-BPS 53
VALUE USR-Final-Rx-Link-Data-Rate 64000-BPS 54
VALUE USR-Initial-Tx-Link-Data-Rate 110-BPS 1
VALUE USR-Initial-Tx-Link-Data-Rate 300-BPS 2
VALUE USR-Initial-Tx-Link-Data-Rate 600-BPS 3
VALUE USR-Initial-Tx-Link-Data-Rate 1200-BPS 4
VALUE USR-Initial-Tx-Link-Data-Rate 2400-BPS 5
VALUE USR-Initial-Tx-Link-Data-Rate 4800-BPS 6
VALUE USR-Initial-Tx-Link-Data-Rate 7200-BPS 7
VALUE USR-Initial-Tx-Link-Data-Rate 9600-BPS 8
VALUE USR-Initial-Tx-Link-Data-Rate 12000-BPS 9
VALUE USR-Initial-Tx-Link-Data-Rate 14400-BPS 10
VALUE USR-Initial-Tx-Link-Data-Rate 16800-BPS 11
VALUE USR-Initial-Tx-Link-Data-Rate 19200-BPS 12
VALUE USR-Initial-Tx-Link-Data-Rate 38400-BPS 13
VALUE USR-Initial-Tx-Link-Data-Rate 75-BPS 14
VALUE USR-Initial-Tx-Link-Data-Rate 450-BPS 15
VALUE USR-Initial-Tx-Link-Data-Rate UNKNOWN-BPS 16
VALUE USR-Initial-Tx-Link-Data-Rate 57600-BPS 17
VALUE USR-Initial-Tx-Link-Data-Rate 21600-BPS 18
VALUE USR-Initial-Tx-Link-Data-Rate 24000-BPS 19
VALUE USR-Initial-Tx-Link-Data-Rate 26400-BPS 20
VALUE USR-Initial-Tx-Link-Data-Rate 28800-BPS 21
VALUE USR-Initial-Tx-Link-Data-Rate 115200-BPS 22
VALUE USR-Initial-Tx-Link-Data-Rate 31200-BPS 23
VALUE USR-Initial-Tx-Link-Data-Rate 33600-BPS 24
VALUE USR-Initial-Tx-Link-Data-Rate 25333-BPS 25
VALUE USR-Initial-Tx-Link-Data-Rate 26666-BPS 26
VALUE USR-Initial-Tx-Link-Data-Rate 28000-BPS 27
VALUE USR-Initial-Tx-Link-Data-Rate 29333-BPS 28
VALUE USR-Initial-Tx-Link-Data-Rate 30666-BPS 29
VALUE USR-Initial-Tx-Link-Data-Rate 32000-BPS 30
VALUE USR-Initial-Tx-Link-Data-Rate 33333-BPS 31
VALUE USR-Initial-Tx-Link-Data-Rate 34666-BPS 32
VALUE USR-Initial-Tx-Link-Data-Rate 36000-BPS 33
VALUE USR-Initial-Tx-Link-Data-Rate 37333-BPS 34
VALUE USR-Initial-Tx-Link-Data-Rate 38666-BPS 35
VALUE USR-Initial-Tx-Link-Data-Rate 40000-BPS 36
VALUE USR-Initial-Tx-Link-Data-Rate 41333-BPS 37
VALUE USR-Initial-Tx-Link-Data-Rate 42666-BPS 38
VALUE USR-Initial-Tx-Link-Data-Rate 44000-BPS 39
VALUE USR-Initial-Tx-Link-Data-Rate 45333-BPS 40
VALUE USR-Initial-Tx-Link-Data-Rate 46666-BPS 41
VALUE USR-Initial-Tx-Link-Data-Rate 48000-BPS 42
VALUE USR-Initial-Tx-Link-Data-Rate 49333-BPS 43
VALUE USR-Initial-Tx-Link-Data-Rate 50666-BPS 44
VALUE USR-Initial-Tx-Link-Data-Rate 52000-BPS 45
VALUE USR-Initial-Tx-Link-Data-Rate 53333-BPS 46
VALUE USR-Initial-Tx-Link-Data-Rate 54666-BPS 47
VALUE USR-Initial-Tx-Link-Data-Rate 56000-BPS 48
VALUE USR-Initial-Tx-Link-Data-Rate 57333-BPS 49
VALUE USR-Initial-Tx-Link-Data-Rate 58666-BPS 50
VALUE USR-Initial-Tx-Link-Data-Rate 60000-BPS 51
VALUE USR-Initial-Tx-Link-Data-Rate 61333-BPS 52
VALUE USR-Initial-Tx-Link-Data-Rate 62666-BPS 53
VALUE USR-Initial-Tx-Link-Data-Rate 64000-BPS 54
VALUE USR-Final-Tx-Link-Data-Rate 110-BPS 1
VALUE USR-Final-Tx-Link-Data-Rate 300-BPS 2
VALUE USR-Final-Tx-Link-Data-Rate 600-BPS 3
VALUE USR-Final-Tx-Link-Data-Rate 1200-BPS 4
VALUE USR-Final-Tx-Link-Data-Rate 2400-BPS 5
VALUE USR-Final-Tx-Link-Data-Rate 4800-BPS 6
VALUE USR-Final-Tx-Link-Data-Rate 7200-BPS 7
VALUE USR-Final-Tx-Link-Data-Rate 9600-BPS 8
VALUE USR-Final-Tx-Link-Data-Rate 12000-BPS 9
VALUE USR-Final-Tx-Link-Data-Rate 14400-BPS 10
VALUE USR-Final-Tx-Link-Data-Rate 16800-BPS 11
VALUE USR-Final-Tx-Link-Data-Rate 19200-BPS 12
VALUE USR-Final-Tx-Link-Data-Rate 38400-BPS 13
VALUE USR-Final-Tx-Link-Data-Rate 75-BPS 14
VALUE USR-Final-Tx-Link-Data-Rate 450-BPS 15
VALUE USR-Final-Tx-Link-Data-Rate UNKNOWN-BPS 16
VALUE USR-Final-Tx-Link-Data-Rate 57600-BPS 17
VALUE USR-Final-Tx-Link-Data-Rate 21600-BPS 18
VALUE USR-Final-Tx-Link-Data-Rate 24000-BPS 19
VALUE USR-Final-Tx-Link-Data-Rate 26400-BPS 20
VALUE USR-Final-Tx-Link-Data-Rate 28800-BPS 21
VALUE USR-Final-Tx-Link-Data-Rate 115200-BPS 22
VALUE USR-Final-Tx-Link-Data-Rate 31200-BPS 23
VALUE USR-Final-Tx-Link-Data-Rate 33600-BPS 24
VALUE USR-Final-Tx-Link-Data-Rate 25333-BPS 25
VALUE USR-Final-Tx-Link-Data-Rate 26666-BPS 26
VALUE USR-Final-Tx-Link-Data-Rate 28000-BPS 27
VALUE USR-Final-Tx-Link-Data-Rate 29333-BPS 28
VALUE USR-Final-Tx-Link-Data-Rate 30666-BPS 29
VALUE USR-Final-Tx-Link-Data-Rate 32000-BPS 30
VALUE USR-Final-Tx-Link-Data-Rate 33333-BPS 31
VALUE USR-Final-Tx-Link-Data-Rate 34666-BPS 32
VALUE USR-Final-Tx-Link-Data-Rate 36000-BPS 33
VALUE USR-Final-Tx-Link-Data-Rate 37333-BPS 34
VALUE USR-Final-Tx-Link-Data-Rate 38666-BPS 35
VALUE USR-Final-Tx-Link-Data-Rate 40000-BPS 36
VALUE USR-Final-Tx-Link-Data-Rate 41333-BPS 37
VALUE USR-Final-Tx-Link-Data-Rate 42666-BPS 38
VALUE USR-Final-Tx-Link-Data-Rate 44000-BPS 39
VALUE USR-Final-Tx-Link-Data-Rate 45333-BPS 40
VALUE USR-Final-Tx-Link-Data-Rate 46666-BPS 41
VALUE USR-Final-Tx-Link-Data-Rate 48000-BPS 42
VALUE USR-Final-Tx-Link-Data-Rate 49333-BPS 43
VALUE USR-Final-Tx-Link-Data-Rate 50666-BPS 44
VALUE USR-Final-Tx-Link-Data-Rate 52000-BPS 45
VALUE USR-Final-Tx-Link-Data-Rate 53333-BPS 46
VALUE USR-Final-Tx-Link-Data-Rate 54666-BPS 47
VALUE USR-Final-Tx-Link-Data-Rate 56000-BPS 48
VALUE USR-Final-Tx-Link-Data-Rate 57333-BPS 49
VALUE USR-Final-Tx-Link-Data-Rate 58666-BPS 50
VALUE USR-Final-Tx-Link-Data-Rate 60000-BPS 51
VALUE USR-Final-Tx-Link-Data-Rate 61333-BPS 52
VALUE USR-Final-Tx-Link-Data-Rate 62666-BPS 53
VALUE USR-Final-Tx-Link-Data-Rate 64000-BPS 54
VALUE USR-Connect-Speed NONE 1
VALUE USR-Connect-Speed 300-BPS 2
VALUE USR-Connect-Speed 1200-BPS 3
VALUE USR-Connect-Speed 2400-BPS 4
VALUE USR-Connect-Speed 4800-BPS 5
VALUE USR-Connect-Speed 7200-BPS 6
VALUE USR-Connect-Speed 9600-BPS 7
VALUE USR-Connect-Speed 12000-BPS 8
VALUE USR-Connect-Speed 14400-BPS 9
VALUE USR-Connect-Speed 16800-BPS 10
VALUE USR-Connect-Speed 19200-BPS 11
VALUE USR-Connect-Speed 21600-BPS 12
VALUE USR-Connect-Speed 28800-BPS 13
VALUE USR-Connect-Speed 38400-BPS 14
VALUE USR-Connect-Speed 57600-BPS 15
VALUE USR-Connect-Speed 115200-BPS 16
VALUE USR-Connect-Speed 288000-BPS 17
VALUE USR-Connect-Speed 75-1200-BPS 18
VALUE USR-Connect-Speed 1200-75-BPS 19
VALUE USR-Connect-Speed 24000-BPS 20
VALUE USR-Connect-Speed 26400-BPS 21
VALUE USR-Connect-Speed 31200-BPS 22
VALUE USR-Connect-Speed 33600-BPS 23
VALUE USR-Connect-Speed 33333-BPS 24
VALUE USR-Connect-Speed 37333-BPS 25
VALUE USR-Connect-Speed 41333-BPS 26
VALUE USR-Connect-Speed 42666-BPS 27
VALUE USR-Connect-Speed 44000-BPS 28
VALUE USR-Connect-Speed 45333-BPS 29
VALUE USR-Connect-Speed 46666-BPS 30
VALUE USR-Connect-Speed 48000-BPS 31
VALUE USR-Connect-Speed 49333-BPS 32
VALUE USR-Connect-Speed 50666-BPS 33
VALUE USR-Connect-Speed 52000-BPS 34
VALUE USR-Connect-Speed 53333-BPS 35
VALUE USR-Connect-Speed 54666-BPS 36
VALUE USR-Connect-Speed 56000-BPS 37
VALUE USR-Connect-Speed 57333-BPS 38
VALUE USR-Connect-Speed 64000-BPS 39
VALUE USR-Connect-Speed 25333-BPS 40
VALUE USR-Connect-Speed 26666-BPS 41
VALUE USR-Connect-Speed 28000-BPS 42
VALUE USR-Connect-Speed 29333-BPS 43
VALUE USR-Connect-Speed 30666-BPS 44
VALUE USR-Connect-Speed 32000-BPS 45
VALUE USR-Connect-Speed 34666-BPS 46
VALUE USR-Connect-Speed 36000-BPS 47
VALUE USR-Connect-Speed 38666-BPS 48
VALUE USR-Connect-Speed 40000-BPS 49
VALUE USR-Connect-Speed 58666-BPS 50
VALUE USR-Connect-Speed 60000-BPS 51
VALUE USR-Connect-Speed 61333-BPS 52
VALUE USR-Connect-Speed 62666-BPS 53
VALUE USR-Sync-Async-Mode Asynchronous 1
VALUE USR-Sync-Async-Mode Synchronous 2
VALUE USR-Originate-Answer-Mode Originate_in_Originate_Mode 1
VALUE USR-Originate-Answer-Mode Originate_in_Answer_Mode 2
VALUE USR-Originate-Answer-Mode Answer_in_Originate_Mode 3
VALUE USR-Originate-Answer-Mode Answer_in_Answer_Mode 4
VALUE USR-Modulation-Type usRoboticsHST 1
VALUE USR-Modulation-Type ccittV32 2
VALUE USR-Modulation-Type ccittV22bis 3
VALUE USR-Modulation-Type bell103 4
VALUE USR-Modulation-Type ccittV21 5
VALUE USR-Modulation-Type bell212 6
VALUE USR-Modulation-Type ccittV32bis 7
VALUE USR-Modulation-Type ccittV23 8
VALUE USR-Modulation-Type negotiationFailed 9
VALUE USR-Modulation-Type bell208b 10
VALUE USR-Modulation-Type v21FaxClass1 11
VALUE USR-Modulation-Type v27FaxClass1 12
VALUE USR-Modulation-Type v29FaxClass1 13
VALUE USR-Modulation-Type v17FaxClass1 14
VALUE USR-Modulation-Type v21FaxClass2 15
VALUE USR-Modulation-Type v27FaxClass2 16
VALUE USR-Modulation-Type v29FaxClass2 17
VALUE USR-Modulation-Type v17FaxClass2 18
VALUE USR-Modulation-Type v32Terbo 19
VALUE USR-Modulation-Type v34 20
VALUE USR-Modulation-Type vFC 21
VALUE USR-Modulation-Type v34plus 22
VALUE USR-Modulation-Type x2 23
VALUE USR-Modulation-Type v110 24
VALUE USR-Modulation-Type v120 25
VALUE USR-Modulation-Type x75 26
VALUE USR-Modulation-Type asyncSyncPPP 27
VALUE USR-Modulation-Type clearChannel 28
VALUE USR-Modulation-Type x2client 29
VALUE USR-Modulation-Type x2symmetric 30
VALUE USR-Modulation-Type piafs 31
VALUE USR-Modulation-Type x2version2 32
VALUE USR-Modulation-Type v90Analog 33
VALUE USR-Modulation-Type v90Digital 34
VALUE USR-Modulation-Type v90AllDigital 35
VALUE Initial-Modulation-Type usRoboticsHST 1
VALUE Initial-Modulation-Type ccittV32 2
VALUE Initial-Modulation-Type ccittV22bis 3
VALUE Initial-Modulation-Type bell103 4
VALUE Initial-Modulation-Type ccittV21 5
VALUE Initial-Modulation-Type bell212 6
VALUE Initial-Modulation-Type ccittV32bis 7
VALUE Initial-Modulation-Type ccittV23 8
VALUE Initial-Modulation-Type negotiationFailed 9
VALUE Initial-Modulation-Type bell208b 10
VALUE Initial-Modulation-Type v21FaxClass1 11
VALUE Initial-Modulation-Type v27FaxClass1 12
VALUE Initial-Modulation-Type v29FaxClass1 13
VALUE Initial-Modulation-Type v17FaxClass1 14
VALUE Initial-Modulation-Type v21FaxClass2 15
VALUE Initial-Modulation-Type v27FaxClass2 16
VALUE Initial-Modulation-Type v29FaxClass2 17
VALUE Initial-Modulation-Type v17FaxClass2 18
VALUE Initial-Modulation-Type v32Terbo 19
VALUE Initial-Modulation-Type v34 20
VALUE Initial-Modulation-Type vFC 21
VALUE Initial-Modulation-Type v34plus 22
VALUE Initial-Modulation-Type x2 23
VALUE Initial-Modulation-Type v110 24
VALUE Initial-Modulation-Type v120 25
VALUE Initial-Modulation-Type x75 26
VALUE Initial-Modulation-Type asyncSyncPPP 27
VALUE Initial-Modulation-Type clearChannel 28
VALUE Initial-Modulation-Type x2client 29
VALUE Initial-Modulation-Type x2symmetric 30
VALUE Initial-Modulation-Type piafs 31
VALUE Initial-Modulation-Type x2version2 32
VALUE Initial-Modulation-Type v90Analogue 33
VALUE Initial-Modulation-Type v90Digital 34
VALUE Initial-Modulation-Type v90AllDigital 35
VALUE USR-Connect-Term-Reason dtrDrop 1
VALUE USR-Connect-Term-Reason escapeSequence 2
VALUE USR-Connect-Term-Reason athCommand 3
VALUE USR-Connect-Term-Reason carrierLoss 4
VALUE USR-Connect-Term-Reason inactivityTimout 5
VALUE USR-Connect-Term-Reason mnpIncompatible 6
VALUE USR-Connect-Term-Reason undefined 7
VALUE USR-Connect-Term-Reason remotePassword 8
VALUE USR-Connect-Term-Reason linkPassword 9
VALUE USR-Connect-Term-Reason retransmitLimit 10
VALUE USR-Connect-Term-Reason linkDisconnectMsgReceived 11
VALUE USR-Connect-Term-Reason noLoopCurrent 12
VALUE USR-Connect-Term-Reason invalidSpeed 13
VALUE USR-Connect-Term-Reason unableToRetrain 14
VALUE USR-Connect-Term-Reason managementCommand 15
VALUE USR-Connect-Term-Reason noDialTone 16
VALUE USR-Connect-Term-Reason keyAbort 17
VALUE USR-Connect-Term-Reason lineBusy 18
VALUE USR-Connect-Term-Reason noAnswer 19
VALUE USR-Connect-Term-Reason voice 20
VALUE USR-Connect-Term-Reason noAnswerTone 21
VALUE USR-Connect-Term-Reason noCarrier 22
VALUE USR-Connect-Term-Reason undetermined 23
VALUE USR-Connect-Term-Reason v42SabmeTimeout 24
VALUE USR-Connect-Term-Reason v42BreakTimeout 25
VALUE USR-Connect-Term-Reason v42DisconnectCmd 26
VALUE USR-Connect-Term-Reason v42IdExchangeFail 27
VALUE USR-Connect-Term-Reason v42BadSetup 28
VALUE USR-Connect-Term-Reason v42InvalidCodeWord 29
VALUE USR-Connect-Term-Reason v42StringToLong 30
VALUE USR-Connect-Term-Reason v42InvalidCommand 31
VALUE USR-Connect-Term-Reason none 32
VALUE USR-Connect-Term-Reason v32Cleardown 33
VALUE USR-Connect-Term-Reason dialSecurity 34
VALUE USR-Connect-Term-Reason remoteAccessDenied 35
VALUE USR-Connect-Term-Reason loopLoss 36
VALUE USR-Connect-Term-Reason ds0Teardown 37
VALUE USR-Connect-Term-Reason promptNotEnabled 38
VALUE USR-Connect-Term-Reason noPromptingInSync 39
VALUE USR-Connect-Term-Reason nonArqMode 40
VALUE USR-Connect-Term-Reason modeIncompatible 41
VALUE USR-Connect-Term-Reason noPromptInNonARQ 42
VALUE USR-Connect-Term-Reason dialBackLink 43
VALUE USR-Connect-Term-Reason linkAbort 44
VALUE USR-Connect-Term-Reason autopassFailed 45
VALUE USR-Connect-Term-Reason pbGenericError 46
VALUE USR-Connect-Term-Reason pbLinkErrTxPreAck 47
VALUE USR-Connect-Term-Reason pbLinkErrTxTardyACK 48
VALUE USR-Connect-Term-Reason pbTransmitBusTimeout 49
VALUE USR-Connect-Term-Reason pbReceiveBusTimeout 50
VALUE USR-Connect-Term-Reason pbLinkErrTxTAL 51
VALUE USR-Connect-Term-Reason pbLinkErrRxTAL 52
VALUE USR-Connect-Term-Reason pbTransmitMasterTimeout 53
VALUE USR-Connect-Term-Reason pbClockMissing 54
VALUE USR-Connect-Term-Reason pbReceivedLsWhileLinkUp 55
VALUE USR-Connect-Term-Reason pbOutOfSequenceFrame 56
VALUE USR-Connect-Term-Reason pbBadFrame 57
VALUE USR-Connect-Term-Reason pbAckWaitTimeout 58
VALUE USR-Connect-Term-Reason pbReceivedAckSeqErr 59
VALUE USR-Connect-Term-Reason pbReceiveOvrflwRNRFail 60
VALUE USR-Connect-Term-Reason pbReceiveMsgBufOvrflw 61
VALUE USR-Connect-Term-Reason rcvdGatewayDiscCmd 62
VALUE USR-Connect-Term-Reason tokenPassingTimeout 63
VALUE USR-Connect-Term-Reason dspInterruptTimeout 64
VALUE USR-Connect-Term-Reason mnpProtocolViolation 65
VALUE USR-Connect-Term-Reason class2FaxHangupCmd 66
VALUE USR-Connect-Term-Reason hstSpeedSwitchTimeout 67
VALUE USR-Connect-Term-Reason tooManyUnacked 68
VALUE USR-Connect-Term-Reason timerExpired 69
VALUE USR-Connect-Term-Reason t1Glare 70
VALUE USR-Connect-Term-Reason priDialoutRqTimeout 71
VALUE USR-Connect-Term-Reason abortAnlgDstOvrIsdn 72
VALUE USR-Connect-Term-Reason normalUserCallClear 73
VALUE USR-Connect-Term-Reason normalUnspecified 74
VALUE USR-Connect-Term-Reason bearerIncompatibility 75
VALUE USR-Connect-Term-Reason protocolErrorEvent 76
VALUE USR-Connect-Term-Reason abnormalDisconnect 77
VALUE USR-Connect-Term-Reason invalidCauseValue 78
VALUE USR-Connect-Term-Reason resourceUnavailable 79
VALUE USR-Connect-Term-Reason remoteHungUpDuringTraining 80
VALUE USR-Connect-Term-Reason trainingTimeout 81
VALUE USR-Connect-Term-Reason incomingModemNotAvailable 82
VALUE USR-Connect-Term-Reason incomingInvalidBearerCap 83
VALUE USR-Connect-Term-Reason incomingInvalidChannelID 84
VALUE USR-Connect-Term-Reason incomingInvalidProgInd 85
VALUE USR-Connect-Term-Reason incomingInvalidCallingPty 86
VALUE USR-Connect-Term-Reason incomingInvalidCalledPty 87
VALUE USR-Connect-Term-Reason incomingCallBlock 88
VALUE USR-Connect-Term-Reason incomingLoopStNoRingOff 89
VALUE USR-Connect-Term-Reason outgoingTelcoDisconnect 90
VALUE USR-Connect-Term-Reason outgoingEMWinkTimeout 91
VALUE USR-Connect-Term-Reason outgoingEMWinkTooShort 92
VALUE USR-Connect-Term-Reason outgoingNoChannelAvail 93
VALUE USR-Connect-Term-Reason dspReboot 94
VALUE USR-Connect-Term-Reason noDSPRespToKA 95
VALUE USR-Connect-Term-Reason noDSPRespToDisc 96
VALUE USR-Connect-Term-Reason dspTailPtrInvalid 97
VALUE USR-Connect-Term-Reason dspHeadPtrInvalid 98
VALUE USR-Failure-to-Connect-Reason dtrDrop 1
VALUE USR-Failure-to-Connect-Reason escapeSequence 2
VALUE USR-Failure-to-Connect-Reason athCommand 3
VALUE USR-Failure-to-Connect-Reason carrierLoss 4
VALUE USR-Failure-to-Connect-Reason inactivityTimout 5
VALUE USR-Failure-to-Connect-Reason mnpIncompatible 6
VALUE USR-Failure-to-Connect-Reason undefined 7
VALUE USR-Failure-to-Connect-Reason remotePassword 8
VALUE USR-Failure-to-Connect-Reason linkPassword 9
VALUE USR-Failure-to-Connect-Reason retransmitLimit 10
VALUE USR-Failure-to-Connect-Reason linkDisconnectMsgRec 11
VALUE USR-Failure-to-Connect-Reason noLoopCurrent 12
VALUE USR-Failure-to-Connect-Reason invalidSpeed 13
VALUE USR-Failure-to-Connect-Reason unableToRetrain 14
VALUE USR-Failure-to-Connect-Reason managementCommand 15
VALUE USR-Failure-to-Connect-Reason noDialTone 16
VALUE USR-Failure-to-Connect-Reason keyAbort 17
VALUE USR-Failure-to-Connect-Reason lineBusy 18
VALUE USR-Failure-to-Connect-Reason noAnswer 19
VALUE USR-Failure-to-Connect-Reason voice 20
VALUE USR-Failure-to-Connect-Reason noAnswerTone 21
VALUE USR-Failure-to-Connect-Reason noCarrier 22
VALUE USR-Failure-to-Connect-Reason undetermined 23
VALUE USR-Failure-to-Connect-Reason v42SabmeTimeout 24
VALUE USR-Failure-to-Connect-Reason v42BreakTimeout 25
VALUE USR-Failure-to-Connect-Reason v42DisconnectCmd 26
VALUE USR-Failure-to-Connect-Reason v42IdExchangeFail 27
VALUE USR-Failure-to-Connect-Reason v42BadSetup 28
VALUE USR-Failure-to-Connect-Reason v42InvalidCodeWord 29
VALUE USR-Failure-to-Connect-Reason v42StringToLong 30
VALUE USR-Failure-to-Connect-Reason v42InvalidCommand 31
VALUE USR-Failure-to-Connect-Reason none 32
VALUE USR-Failure-to-Connect-Reason v32Cleardown 33
VALUE USR-Failure-to-Connect-Reason dialSecurity 34
VALUE USR-Failure-to-Connect-Reason remoteAccessDenied 35
VALUE USR-Failure-to-Connect-Reason loopLoss 36
VALUE USR-Failure-to-Connect-Reason ds0Teardown 37
VALUE USR-Failure-to-Connect-Reason promptNotEnabled 38
VALUE USR-Failure-to-Connect-Reason noPromptingInSync 39
VALUE USR-Failure-to-Connect-Reason nonArqMode 40
VALUE USR-Failure-to-Connect-Reason modeIncompatible 41
VALUE USR-Failure-to-Connect-Reason noPromptInNonARQ 42
VALUE USR-Failure-to-Connect-Reason dialBackLink 43
VALUE USR-Failure-to-Connect-Reason linkAbort 44
VALUE USR-Failure-to-Connect-Reason autopassFailed 45
VALUE USR-Failure-to-Connect-Reason pbGenericError 46
VALUE USR-Failure-to-Connect-Reason pbLinkErrTxPreAck 47
VALUE USR-Failure-to-Connect-Reason pbLinkErrTxTardyACK 48
VALUE USR-Failure-to-Connect-Reason pbTransmitBusTimeout 49
VALUE USR-Failure-to-Connect-Reason pbReceiveBusTimeout 50
VALUE USR-Failure-to-Connect-Reason pbLinkErrTxTAL 51
VALUE USR-Failure-to-Connect-Reason pbLinkErrRxTAL 52
VALUE USR-Failure-to-Connect-Reason pbTransmitMasterTimeout 53
VALUE USR-Failure-to-Connect-Reason pbClockMissing 54
VALUE USR-Failure-to-Connect-Reason pbReceivedLsWhileLinkUp 55
VALUE USR-Failure-to-Connect-Reason pbOutOfSequenceFrame 56
VALUE USR-Failure-to-Connect-Reason pbBadFrame 57
VALUE USR-Failure-to-Connect-Reason pbAckWaitTimeout 58
VALUE USR-Failure-to-Connect-Reason pbReceivedAckSeqErr 59
VALUE USR-Failure-to-Connect-Reason pbReceiveOvrflwRNRFail 60
VALUE USR-Failure-to-Connect-Reason pbReceiveMsgBufOvrflw 61
VALUE USR-Failure-to-Connect-Reason rcvdGatewayDiscCmd 62
VALUE USR-Failure-to-Connect-Reason tokenPassingTimeout 63
VALUE USR-Failure-to-Connect-Reason dspInterruptTimeout 64
VALUE USR-Failure-to-Connect-Reason mnpProtocolViolation 65
VALUE USR-Failure-to-Connect-Reason class2FaxHangupCmd 66
VALUE USR-Failure-to-Connect-Reason hstSpeedSwitchTimeout 67
VALUE USR-Failure-to-Connect-Reason tooManyUnacked 68
VALUE USR-Failure-to-Connect-Reason timerExpired 69
VALUE USR-Failure-to-Connect-Reason t1Glare 70
VALUE USR-Failure-to-Connect-Reason priDialoutRqTimeout 71
VALUE USR-Failure-to-Connect-Reason abortAnlgDstOvrIsdn 72
VALUE USR-Failure-to-Connect-Reason normalUserCallClear 73
VALUE USR-Failure-to-Connect-Reason normalUnspecified 74
VALUE USR-Failure-to-Connect-Reason bearerIncompatibility 75
VALUE USR-Failure-to-Connect-Reason protocolErrorEvent 76
VALUE USR-Failure-to-Connect-Reason abnormalDisconnect 77
VALUE USR-Failure-to-Connect-Reason invalidCauseValue 78
VALUE USR-Failure-to-Connect-Reason resourceUnavailable 79
VALUE USR-Failure-to-Connect-Reason remoteHungUpDuringTraining 80
VALUE USR-Failure-to-Connect-Reason trainingTimeout 81
VALUE USR-Failure-to-Connect-Reason incomingModemNotAvailable 82
VALUE USR-Failure-to-Connect-Reason incomingInvalidBearerCap 83
VALUE USR-Failure-to-Connect-Reason incomingInvalidChannelID 84
VALUE USR-Failure-to-Connect-Reason incomingInvalidProgInd 85
VALUE USR-Failure-to-Connect-Reason incomingInvalidCallingPty 86
VALUE USR-Failure-to-Connect-Reason incomingInvalidCalledPty 87
VALUE USR-Failure-to-Connect-Reason incomingCallBlock 88
VALUE USR-Failure-to-Connect-Reason incomingLoopStNoRingOff 89
VALUE USR-Failure-to-Connect-Reason outgoingTelcoDisconnect 90
VALUE USR-Failure-to-Connect-Reason outgoingEMWinkTimeout 91
VALUE USR-Failure-to-Connect-Reason outgoingEMWinkTooShort 92
VALUE USR-Failure-to-Connect-Reason outgoingNoChannelAvail 93
VALUE USR-Failure-to-Connect-Reason dspReboot 94
VALUE USR-Failure-to-Connect-Reason noDSPRespToKA 95
VALUE USR-Failure-to-Connect-Reason noDSPRespToDisc 96
VALUE USR-Failure-to-Connect-Reason dspTailPtrInvalid 97
VALUE USR-Failure-to-Connect-Reason dspHeadPtrInvalid 98
VALUE USR-Simplified-MNP-Levels none 1
VALUE USR-Simplified-MNP-Levels mnpLevel3 2
VALUE USR-Simplified-MNP-Levels mnpLevel4 3
VALUE USR-Simplified-MNP-Levels ccittV42 4
VALUE USR-Simplified-MNP-Levels usRoboticsHST 5
VALUE USR-Simplified-MNP-Levels synchronousNone 6
VALUE USR-Simplified-MNP-Levels mnpLevel2 7
VALUE USR-Simplified-MNP-Levels mnp10 8
VALUE USR-Simplified-MNP-Levels v42Etc 9
VALUE USR-Simplified-MNP-Levels mnp10Etc 10
VALUE USR-Simplified-MNP-Levels lapmEtc 11
VALUE USR-Simplified-MNP-Levels v42Etc2 12
VALUE USR-Simplified-MNP-Levels v42SRej 13
VALUE USR-Simplified-MNP-Levels piafs 14
VALUE USR-Simplified-V42bis-Usage none 1
VALUE USR-Simplified-V42bis-Usage ccittV42bis 2
VALUE USR-Simplified-V42bis-Usage mnpLevel5 3
VALUE USR-Equalization-Type Long 1
VALUE USR-Equalization-Type Short 2
VALUE USR-Fallback-Enabled Disabled 1
VALUE USR-Fallback-Enabled Enabled 2
VALUE USR-Back-Channel-Data-Rate 450BPS 1
VALUE USR-Back-Channel-Data-Rate 300BPS 2
VALUE USR-Back-Channel-Data-Rate None 3
VALUE USR-Device-Connected-To None 1
VALUE USR-Device-Connected-To isdnGateway 2
VALUE USR-Device-Connected-To quadModem 3
VALUE USR-Call-Event-Code notSupported 1
VALUE USR-Call-Event-Code setup 2
VALUE USR-Call-Event-Code usrSetup 3
VALUE USR-Call-Event-Code telcoDisconnect 4
VALUE USR-Call-Event-Code usrDisconnect 5
VALUE USR-Call-Event-Code noFreeModem 6
VALUE USR-Call-Event-Code modemsNotAllowed 7
VALUE USR-Call-Event-Code modemsRejectCall 8
VALUE USR-Call-Event-Code modemSetupTimeout 9
VALUE USR-Call-Event-Code noFreeIGW 10
VALUE USR-Call-Event-Code igwRejectCall 11
VALUE USR-Call-Event-Code igwSetupTimeout 12
VALUE USR-Call-Event-Code noFreeTdmts 13
VALUE USR-Call-Event-Code bcReject 14
VALUE USR-Call-Event-Code ieReject 15
VALUE USR-Call-Event-Code chidReject 16
VALUE USR-Call-Event-Code progReject 17
VALUE USR-Call-Event-Code callingPartyReject 18
VALUE USR-Call-Event-Code calledPartyReject 19
VALUE USR-Call-Event-Code blocked 20
VALUE USR-Call-Event-Code analogBlocked 21
VALUE USR-Call-Event-Code digitalBlocked 22
VALUE USR-Call-Event-Code outOfService 23
VALUE USR-Call-Event-Code busy 24
VALUE USR-Call-Event-Code congestion 25
VALUE USR-Call-Event-Code protocolError 26
VALUE USR-Call-Event-Code noFreeBchannel 27
VALUE USR-Call-Event-Code inOutCallCollision 28
VALUE USR-Call-Event-Code inCallArrival 29
VALUE USR-Call-Event-Code outCallArrival 30
VALUE USR-Call-Event-Code inCallConnect 31
VALUE USR-Call-Event-Code outCallConnect 32
VALUE USR-HARC-Disconnect-Code No-Error 0
VALUE USR-HARC-Disconnect-Code No-Carrier 1
VALUE USR-HARC-Disconnect-Code No-DSR 2
VALUE USR-HARC-Disconnect-Code Timeout 3
VALUE USR-HARC-Disconnect-Code Reset 4
VALUE USR-HARC-Disconnect-Code Call-Drop-Req 5
VALUE USR-HARC-Disconnect-Code Idle-Timeout 6
VALUE USR-HARC-Disconnect-Code Session-Timeout 7
VALUE USR-HARC-Disconnect-Code User-Req-Drop 8
VALUE USR-HARC-Disconnect-Code Host-Req-Drop 9
VALUE USR-HARC-Disconnect-Code Service-Interruption 10
VALUE USR-HARC-Disconnect-Code Service-Unavailable 11
VALUE USR-HARC-Disconnect-Code User-Input-Error 12
VALUE USR-HARC-Disconnect-Code NAS-Drop-For-Callback 13
VALUE USR-HARC-Disconnect-Code NAS-Drop-Misc-Non-Error 14
VALUE USR-HARC-Disconnect-Code NAS-Internal-Error 15
VALUE USR-HARC-Disconnect-Code Line-Busy 16
VALUE USR-HARC-Disconnect-Code Tunnel-Term-Unreach 19
VALUE USR-HARC-Disconnect-Code Tunnel-Refused 20
VALUE USR-HARC-Disconnect-Code Tunnel-Auth-Failed 21
VALUE USR-HARC-Disconnect-Code Tunnel-Session-Timeout 22
VALUE USR-HARC-Disconnect-Code Tunnel-Timeout 23
VALUE USR-HARC-Disconnect-Code Radius-Res-Reclaim 25
VALUE USR-HARC-Disconnect-Code DNIS-Auth-Failed 26
VALUE USR-HARC-Disconnect-Code PAP-Auth-Failure 27
VALUE USR-HARC-Disconnect-Code CHAP-Auth-Failure 28
VALUE USR-HARC-Disconnect-Code PPP-LCP-Failed 29
VALUE USR-HARC-Disconnect-Code PPP-NCP-Failed 30
VALUE USR-HARC-Disconnect-Code Radius-Timeout 31
VALUE USR-CCP-Algorithm NONE 1
VALUE USR-CCP-Algorithm Stac 2
VALUE USR-CCP-Algorithm MS 3
VALUE USR-CCP-Algorithm Any 4
VALUE USR-Tunnel-Security None 0
VALUE USR-Tunnel-Security Control-Only 1
VALUE USR-Tunnel-Security Data-Only 2
VALUE USR-Tunnel-Security Both-Data-and-Control 3
VALUE USR-RMMIE-Status notEnabledInLocalModem 1
VALUE USR-RMMIE-Status notDetectedInRemoteModem 2
VALUE USR-RMMIE-Status ok 3
VALUE USR-RMMIE-x2-Status notOperational 1
VALUE USR-RMMIE-x2-Status operational 2
VALUE USR-RMMIE-x2-Status x2Disabled 3
VALUE USR-RMMIE-x2-Status v8Disabled 4
VALUE USR-RMMIE-x2-Status remote3200Disabled 5
VALUE USR-RMMIE-x2-Status invalidSpeedSetting 6
VALUE USR-RMMIE-x2-Status v8NotDetected 7
VALUE USR-RMMIE-x2-Status x2NotDetected 8
VALUE USR-RMMIE-x2-Status incompatibleVersion 9
VALUE USR-RMMIE-x2-Status incompatibleModes 10
VALUE USR-RMMIE-x2-Status local3200Disabled 11
VALUE USR-RMMIE-x2-Status excessHighFrequencyAtten 12
VALUE USR-RMMIE-x2-Status connectNotSupport3200 13
VALUE USR-RMMIE-x2-Status retrainBeforeConnection 14
VALUE USR-RMMIE-Planned-Disconnect none 1
VALUE USR-RMMIE-Planned-Disconnect dteNotReady 2
VALUE USR-RMMIE-Planned-Disconnect dteInterfaceError 3
VALUE USR-RMMIE-Planned-Disconnect dteRequest 4
VALUE USR-RMMIE-Planned-Disconnect escapeToOnlineCommandMode 5
VALUE USR-RMMIE-Planned-Disconnect athCommand 6
VALUE USR-RMMIE-Planned-Disconnect inactivityTimeout 7
VALUE USR-RMMIE-Planned-Disconnect arqProtocolError 8
VALUE USR-RMMIE-Planned-Disconnect arqProtocolRetransmitLim 9
VALUE USR-RMMIE-Planned-Disconnect invalidComprDataCodeword 10
VALUE USR-RMMIE-Planned-Disconnect invalidComprDataStringLen 11
VALUE USR-RMMIE-Planned-Disconnect invalidComprDataCommand 12
VALUE USR-RMMIE-Last-Update-Event none 1
VALUE USR-RMMIE-Last-Update-Event initialConnection 2
VALUE USR-RMMIE-Last-Update-Event retrain 3
VALUE USR-RMMIE-Last-Update-Event speedShift 4
VALUE USR-RMMIE-Last-Update-Event plannedDisconnect 5
VALUE USR-Request-Type Access-Request 1
VALUE USR-Request-Type Access-Accept 2
VALUE USR-Request-Type Access-Reject 3
VALUE USR-Request-Type Accounting-Request 4
VALUE USR-Request-Type Accounting-Response 5
VALUE USR-Request-Type Access-Password-Change 7
VALUE USR-Request-Type Access-Password-Ack 8
VALUE USR-Request-Type Access-Password-Reject 9
VALUE USR-Request-Type Access-Challenge 11
VALUE USR-Request-Type Status-Server 12
VALUE USR-Request-Type Status-Client 13
VALUE USR-Request-Type Resource-Free-Request 21
VALUE USR-Request-Type Resource-Free-Response 22
VALUE USR-Request-Type Resource-Query-Request 23
VALUE USR-Request-Type Resource-Query-Response 24
VALUE USR-Request-Type Disconnect-User 25
VALUE USR-Request-Type NAS-Reboot-Request 26
VALUE USR-Request-Type NAS-Reboot-Response 27
VALUE USR-Request-Type Tacacs-Message 253
VALUE USR-Request-Type Reserved 255
VALUE USR-PW_Framed_Routing_V2 Off 0
VALUE USR-PW_Framed_Routing_V2 On 1
VALUE USR-Syslog-Tap Off 0
VALUE USR-Syslog-Tap Raw 1
VALUE USR-Syslog-Tap Framed 2
VALUE USR-Speed-Of-Connection Auto 0
VALUE USR-Speed-Of-Connection 56 1
VALUE USR-Speed-Of-Connection 64 2
VALUE USR-Speed-Of-Connection Voice 3
VALUE USR-Expansion-Algorithm Constant 1
VALUE USR-Expansion-Algorithm Linear 2
VALUE USR-Compression-Algorithm None 0
VALUE USR-Compression-Algorithm Stac 1
VALUE USR-Compression-Algorithm Ascend 2
VALUE USR-Compression-Algorithm Microsoft 3
VALUE USR-Compression-Algorithm Auto 4
VALUE USR-Compression-Reset-Mode Auto 0
VALUE USR-Compression-Reset-Mode Reset-Every-Packet 1
VALUE USR-Compression-Reset-Mode Reset-On-Error 2
VALUE USR-Filter-Zones enabled 1
VALUE USR-Filter-Zones disabled 2
VALUE USR-Bridging enabled 1
VALUE USR-Bridging disabled 2
VALUE USR-Appletalk enabled 1
VALUE USR-Appletalk disabled 2
VALUE USR-Spoofing enabled 1
VALUE USR-Spoofing disabled 2
VALUE USR-Routing-Protocol Rip1 1
VALUE USR-Routing-Protocol Rip2 2
VALUE USR-IPX-Routing none 0
VALUE USR-IPX-Routing send 1
VALUE USR-IPX-Routing listen 2
VALUE USR-IPX-Routing respond 3
VALUE USR-IPX-Routing all 4
VALUE USR-IPX-WAN enabled 1
VALUE USR-IPX-WAN disabled 2
VALUE USR-IP-Default-Route-Option enabled 1
VALUE USR-IP-Default-Route-Option disabled 2
VALUE USR-IP-RIP-Policies SendDefault 0x0
VALUE USR-IP-RIP-Policies SendRoutes 0x2
VALUE USR-IP-RIP-Policies SendSubnets 0x4
VALUE USR-IP-RIP-Policies AcceptDefault 0x8
VALUE USR-IP-RIP-Policies SplitHorizon 0x10
VALUE USR-IP-RIP-Policies PoisonReserve 0x20
VALUE USR-IP-RIP-Policies FlashUpdate 0x40
VALUE USR-IP-RIP-Policies SimpleAuth 0x80
VALUE USR-IP-RIP-Policies V1Send 0x100
VALUE USR-IP-RIP-Policies V1Receive 0x200
VALUE USR-IP-RIP-Policies V2Receive 0x400
VALUE USR-IP-RIP-Policies Silent 0x80000000
VALUE USR-Callback-Type Normal 1
VALUE USR-Callback-Type ANI 2
VALUE USR-Callback-Type Static 3
VALUE USR-Callback-Type Dynamic 4
VALUE USR-Request-Type Access-Request 1
VALUE USR-Request-Type Access-Accept 2
VALUE USR-Request-Type Access-Reject 3
VALUE USR-Request-Type Accounting-Request 4
VALUE USR-Request-Type Accounting-Response 5
# The next three non standard packet types are used by
# US Robotics Security/Accounting Server
VALUE USR-Request-Type Access-Password-Change 7
VALUE USR-Request-Type Access-Password-Ack 8
VALUE USR-Request-Type Access-Password-Reject 9
VALUE USR-Request-Type Access-Challenge 11
VALUE USR-Request-Type Status-Server 12
VALUE USR-Request-Type Status-Client 13
# Non standard packet types used by NetServer to implement
# resource management and NAS reboot conditions
VALUE USR-Request-Type Resource-Free-Request 21
VALUE USR-Request-Type Resource-Free-Response 22
VALUE USR-Request-Type Resource-Query-Request 23
VALUE USR-Request-Type Resource-Query-Response 24
VALUE USR-Request-Type Disconnect-User 25
VALUE USR-Request-Type NAS-Reboot-Request 26
VALUE USR-Request-Type NAS-Reboot-Response 27
# This value is used for Tacacs Plus translation
VALUE USR-Request-Type Tacacs-Message 253
VALUE USR-Request-Type Reserved 255
VALUE USR-NAS-Type 3Com-NMC 0
VALUE USR-NAS-Type 3Com-NETServer 1
VALUE USR-NAS-Type 3Com-HiPerArc 2
VALUE USR-NAS-Type TACACS+-Server 3
VALUE USR-NAS-Type 3Com-SA-Server 4
VALUE USR-NAS-Type Ascend 5
VALUE USR-NAS-Type Generic-RADIUS 6
VALUE USR-NAS-Type 3Com-NETBuilder-II 7
VALUE USR-Auth-Mode Auth-3Com 0
VALUE USR-Auth-Mode Auth-Ace 1
VALUE USR-Auth-Mode Auth-Safeword 2
VALUE USR-Auth-Mode Auth-UNIX-PW 3
VALUE USR-Auth-Mode Auth-Defender 4
VALUE USR-Auth-Mode Auth-TACACSP 5
VALUE USR-Auth-Mode Auth-Netware 6
VALUE USR-Auth-Mode Auth-Skey 7
VALUE USR-Auth-Mode Auth-EAP-Proxy 8
VALUE USR-Auth-Mode Auth-UNIX-Crypt 9
#
# Valemount Networks Corporation specific radius attributes
# networks@valemount.com
#
# $Id: dictionary.valemount,v 1.1 2006/11/14 17:44:59 lem Exp $
#
VENDOR ValemountNetworks 16313
# Rates to give PPPoE customers, can be used in Authentication replies,
# in bits/s
ATTRIBUTE VNC-PPPoE-CBQ-RX 1 integer ValemountNetworks
ATTRIBUTE VNC-PPPoE-CBQ-TX 2 integer ValemountNetworks
# Fallback support for each direction. (1 / 0)
ATTRIBUTE VNC-PPPoE-CBQ-RX-Fallback 3 integer ValemountNetworks
ATTRIBUTE VNC-PPPoE-CBQ-TX-Fallback 4 integer ValemountNetworks
ATTRIBUTE VNC-Splash 10 integer ValemountNetworks
VALUE VNC-Splash Show 1
VALUE VNC-Splash No-Show 0
#
# dictionary.versanet Vendor specfic attributes for versanet
#
#
# VersaNet Communications, Inc.
# Http://www.versa-net.com
#
#
#Versanet add Vendor specific terminal cause in our radius group.
#You can follow this to set it in NAS box.
#
# >> gr radius
# >> sh
# >> set 34 23
# >> co
#
#This will let our unit transfer every detail terminal cause
#information to Redius server's accounting log file and
#save as "Vendor Specific=Terminate Cause".
#
# Version: @(#)dictionary.versanet 1.00 22-Jul-1999 support@versanetcomm.com
#
VENDOR Versanet 2180
ATTRIBUTE Versanet-Termination-Cause 1 integer Versanet
VALUE Versanet-Termination-Cause Normal-Hangup-No-Error-Occurred 0
VALUE Versanet-Termination-Cause Call-Waiting-Caused-Disconnect 3
VALUE Versanet-Termination-Cause Physical-Carrier-Loss 4
VALUE Versanet-Termination-Cause No-err-correction-at-other-end 5
VALUE Versanet-Termination-Cause No-resp-to-feature-negotiation 6
VALUE Versanet-Termination-Cause 1st-modem-async-only-2nd-sync 7
VALUE Versanet-Termination-Cause No-framing-technique-in-common 8
VALUE Versanet-Termination-Cause No-protocol-in-common 9
VALUE Versanet-Termination-Cause Bad-resp-to-feature-negotiation 10
VALUE Versanet-Termination-Cause No-sync-info-from-remote-modem 11
VALUE Versanet-Termination-Cause Normal-Hangup-by-Remote-modem 12
VALUE Versanet-Termination-Cause Retransmission-limit-reached 13
VALUE Versanet-Termination-Cause Protocol-violation-occurred 14
VALUE Versanet-Termination-Cause Lost-DTR 15
VALUE Versanet-Termination-Cause Received-GSTN-cleardown 16
VALUE Versanet-Termination-Cause Inactivity-timeout 17
VALUE Versanet-Termination-Cause Speed-not-supported 18
VALUE Versanet-Termination-Cause Long-space-disconnect 19
VALUE Versanet-Termination-Cause Key-abort-disconnect 20
VALUE Versanet-Termination-Cause Clears-previous-disc-reason 21
VALUE Versanet-Termination-Cause No-connection-established 22
VALUE Versanet-Termination-Cause Disconnect-after-three-retrains 23
# Copyright (C) 2007-2016, AllWorldIT
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The FreeRADIUS Server Project
#
# The following dictionary file is a derivative work of the dictionary file
# from the FreeRADIUS Server Project, which is licensed GPLv2. This file
# therefore is also licensed under the terms of the GNU Public License,
# verison 2
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# dictionary.wispr
#
......
##############################################################################
#
# XEDIA, AP series routers
# From Yard RADIUS, and Piotr Orlewicz, porlewicz@teleton.pl www.real-data.pl
#
# $Id: dictionary.xedia,v 1.1 2006/11/14 17:44:59 lem Exp $
#
#############################################################################
VENDOR Xedia 838
ATTRIBUTE Xedia-DNS-Server 1 ipaddr Xedia
ATTRIBUTE Xedia-NetBios-Server 2 ipaddr Xedia
ATTRIBUTE Xedia-Address-Pool 3 string Xedia
ATTRIBUTE Xedia-PPP-Echo-Interval 4 integer Xedia
ATTRIBUTE Xedia-SSH-Privileges 5 integer Xedia
ATTRIBUTE Xedia-Client-Access-Network 6 string Xedia
package Radius::Dictionary;
# COPYRIGHT AND LICENSE
#
# Copyright 2007-2016, AllWorldIT
#
# Original work (c) Christopher Masto. Changes (c) 2002,2003 Luis
# E. Muñoz <luismunoz@cpan.org>.
#
# This software can be used under the same terms as perl itself. It also
# carries the same warranties.
#
# Please send bug reports (or patches) as well as feedback and
# suggestions to
#
# luismunoz@cpan.org
#
# When submitting bugs, it is very important that you include the
# relevant information for reproducing the bug. Packet dumps are most
# useful.
package smradius::Radius::Dictionary;
use strict;
use warnings;
......@@ -31,9 +50,9 @@ sub new {
sub readfile {
my ($self, $filename) = @_;
open(DICT, "< $filename") or return undef;
open(my $DICT, "<", $filename) or return;
while (defined(my $l = <DICT>)) {
while (defined(my $l = <$DICT>)) {
next if $l =~ /^\#/;
next unless my @l = split /\s+/, $l;
......@@ -166,7 +185,8 @@ sub readfile {
warn "Warning: Weird dictionary line: $l\n";
}
}
close DICT;
close $DICT;
return 1;
}
# Accessors for standard attributes
......
package Radius::Packet;
# COPYRIGHT AND LICENSE
#
# Copyright 2007-2016, AllWorldIT
#
# Original work (c) Christopher Masto. Changes (c) 2002,2003 Luis
# E. Muñoz <luismunoz@cpan.org>.
#
# This software can be used under the same terms as perl itself. It also
# carries the same warranties.
#
# Please send bug reports (or patches) as well as feedback and
# suggestions to
#
# luismunoz@cpan.org
#
# When submitting bugs, it is very important that you include the
# relevant information for reproducing the bug. Packet dumps are most
# useful.
package smradius::Radius::Packet;
use strict;
require Exporter;
......@@ -13,7 +32,7 @@ $VSA = 26; # Type assigned in RFC2138 to the
# Vendor-Specific Attributes
# Be sure our dictionaries are current
use Radius::Dictionary 1.50;
use smradius::Radius::Dictionary 1.50;
use Carp;
use Socket;
use Digest::MD5;
......
There are notable differences between Packet.pm and the Net::Radius Packet.pm, most notable raw value support.
# Attribute handling functions
# Copyright (C) 2007-2009, AllWorldIT
#
# Copyright (C) 2007-2016, AllWorldIT
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
......@@ -24,24 +24,36 @@ use strict;
use warnings;
# Exporter stuff
require Exporter;
our (@ISA,@EXPORT);
@ISA = qw(Exporter);
use base qw(Exporter);
our (@EXPORT);
@EXPORT = qw(
addAttribute
checkAuthAttribute
checkAcctAttribute
setReplyAttribute
setReplyVAttribute
processConfigAttribute
getAttributeValue
addAttributeConditionalVariable
processAttributeConditionals
);
use AWITPT::Util;
# Check Math::Expression is installed
if (!eval {require Math::Expression; 1;}) {
print STDERR "You're missing Math::Expression, try 'apt-get install libmath-expression-perl'\n";
exit 1;
}
use smradius::logging;
use smradius::util;
# Attributes we do not handle
my @attributeCheckIgnoreList = (
'User-Password'
......@@ -51,42 +63,97 @@ my @attributeReplyIgnoreList = (
'SMRadius-Capping-Traffic-Limit',
'SMRadius-Capping-Uptime-Limit',
'SMRadius-Validity-ValidFrom',
'SMRadius-Validity-ValidTo'
'SMRadius-Validity-ValidTo',
'SMRadius-Validity-ValidWindow',
'SMRadius-Username-Transform',
'SMRadius-Evaluate',
'SMRadius-Peer-Address',
'SMRadius-Disable-WebUITopup',
'SMRadius-AutoTopup-Traffic-Enabled',
'SMRadius-AutoTopup-Traffic-Amount',
'SMRadius-AutoTopup-Traffic-Limit',
'SMRadius-AutoTopup-Traffic-Notify',
'SMRadius-AutoTopup-Traffic-NotifyTemplate',
'SMRadius-AutoTopup-Traffic-Threshold',
'SMRadius-AutoTopup-Uptime-Enabled',
'SMRadius-AutoTopup-Uptime-Amount',
'SMRadius-AutoTopup-Uptime-Limit',
'SMRadius-AutoTopup-Uptime-Notify',
'SMRadius-AutoTopup-Uptime-NotifyTemplate',
'SMRadius-AutoTopup-Uptime-Threshold',
'SMRadius-Config-Filter-Reply-Attribute',
'SMRadius-Config-Filter-Reply-VAttribute',
'SMRadius-FUP-Period',
'SMRadius-FUP-Traffic-Threshold',
);
my @attributeVReplyIgnoreList = (
);
## @fn addAttribute($server,$attributes,$attribute)
## @fn addAttribute($server,$user,$attribute)
# Function to add an attribute to $attributes
#
# @param server Server instance
# @param attributes Hashref of attributes we already have and / or must add to
# @param nattributes Hashref of normal attributes we already have and/or must add to
# @param vattributes Hashref of vendor attributes we already have and/or must add to
# @param attribute Attribute to add, eg. Those from a database
sub addAttribute
{
my ($server,$attributes,$attribute) = @_;
my ($server,$user,$attribute) = @_;
# Check if this is an array
if ($attribute->{'Operator'} =~ s/^\|\|//) {
# Check we have the name, operator AND value
if (!defined($attribute->{'Name'}) || !defined($attribute->{'Operator'}) || !defined($attribute->{'Value'})) {
$server->log(LOG_DEBUG,"[ATTRIBUTES] Problem adding attribute with name = ".prettyUndef($attribute->{'Name'}).
", operator = ".prettyUndef($attribute->{'Operator'}).", value = ".prettyUndef($attribute->{'Value'}));
return;
}
# Clean them up a bit
$attribute->{'Name'} =~ s/\s*(\S+)\s*/$1/;
$attribute->{'Operator'} =~ s/\s*(\S+)\s*/$1/;
# Grab attribute name, operator and value
my $name = $attribute->{'Name'};
my $operator = $attribute->{'Operator'};
my $value = $attribute->{'Value'};
# Default attribute to add is normal
my $attributes = $user->{'Attributes'};
# Check where we must add this attribute, maybe to the vendor attributes?
if ($name =~ /^\[(\d+):(\S+)\]$/) {
my $vendor = $1; $name = $2;
# Set vendor
$attribute->{'Vendor'} = $vendor;
# Reset attribute name
$attribute->{'Name'} = $name;
# Set the attributes to use to the vendor
$attributes = $user->{'VAttributes'};
}
# Check if this is an array
if ($operator =~ s/^\|\|//) {
# Check if we've seen this before
if (defined($attributes->{$attribute->{'Name'}}->{$attribute->{'Operator'}}) &&
ref($attributes->{$attribute->{'Name'}}->{$attribute->{'Operator'}}->{'Value'}) eq "ARRAY" ) {
if (defined($attributes->{$name}->{$operator}) &&
ref($attributes->{$name}->{$operator}->{'Value'}) eq "ARRAY" ) {
# Then add value to end of array
push(@{$attributes->{$attribute->{'Name'}}->{$attribute->{'Operator'}}->{'Value'}}, $attribute->{'Value'});
push(@{$attributes->{$name}->{$operator}->{'Value'}}, $value);
# If we have not seen it before, initialize it
# If we have not seen it before, initialize it
} else {
# Assign attribute
$attributes->{$attribute->{'Name'}}->{$attribute->{'Operator'}} = $attribute;
$attributes->{$name}->{$operator} = $attribute;
# Override type ... else we must create a custom attribute hash, this is dirty, but faster
$attributes->{$attribute->{'Name'}}->{$attribute->{'Operator'}}->{'Value'} = [ $attribute->{'Value'} ];
$attributes->{$name}->{$operator}->{'Value'} = [ $value ];
}
# If its not an array, just add it normally
} else {
$attributes->{$attribute->{'Name'}}->{$attribute->{'Operator'}} = $attribute;
$attributes->{$name}->{$operator} = $attribute;
}
# Process the item incase its a config attribute
return processConfigAttribute($server,$user,$attribute);
}
......@@ -99,7 +166,7 @@ sub addAttribute
# @param attribute Attribute to check, eg. One of the ones from the database
sub checkAuthAttribute
{
my ($server,$packetAttributes,$attribute) = @_;
my ($server,$user,$packetAttributes,$attribute) = @_;
# Check ignore list
......@@ -117,28 +184,31 @@ sub checkAuthAttribute
@attrValues = @{$attribute->{'Value'}};
} else {
@attrValues = ( $attribute->{'Value'} );
}
}
# Get packet attribute value
my $attrVal = $packetAttributes->{$attribute->{'Name'}};
$server->log(LOG_DEBUG,"[ATTRIBUTES] Processing CHECK attribute value ".niceUndef($attrVal)." against: '".
$server->log(LOG_DEBUG,"[ATTRIBUTES] Processing CHECK attribute value ".prettyUndef($attrVal)." against: '".
$attribute->{'Name'}."' ".$attribute->{'Operator'}." '".join("','",@attrValues)."'");
# Loop with all the test attribute values
foreach my $tattrVal (@attrValues) {
foreach my $tattrVal (@attrValues) {
# Sanitize the operator
my ($operator) = ($attribute->{'Operator'} =~ /^(?:\|\|)?(.*)$/);
# Operator: ==
#
# Use: Attribute == Value
# As a check item, it matches if the named attribute is present in the request,
# AND has the given value.
#
if ($attribute->{'Operator'} eq '==' ) {
if ($operator eq '==' ) {
# Check for correct value
if (defined($attrVal) && $attrVal eq $tattrVal) {
$matched = 1;
}
# Operator: >
#
# Use: Attribute > Value
......@@ -146,8 +216,8 @@ sub checkAuthAttribute
# with a value greater than the one given.
#
# Not allowed as a reply item.
} elsif ($attribute->{'Operator'} eq '>') {
} elsif ($operator eq '>') {
if (defined($attrVal) && $attrVal =~ /^[0-9]+$/) {
# Check for correct value
if ($attrVal > $tattrVal) {
......@@ -156,7 +226,7 @@ sub checkAuthAttribute
} else {
$server->log(LOG_WARN,"[ATTRIBUTES] - Attribute '".$attribute->{'Name'}."' is NOT a number!");
}
# Operator: <
#
# Use: Attribute < Value
......@@ -164,13 +234,13 @@ sub checkAuthAttribute
# with a value less than the one given.
#
# Not allowed as a reply item.
} elsif ($attribute->{'Operator'} eq '<') {
} elsif ($operator eq '<') {
# Check for correct value
if (defined($attrVal) && $attrVal < $tattrVal) {
$matched = 1;
}
# Operator: <=
#
# Use: Attribute <= Value
......@@ -178,13 +248,13 @@ sub checkAuthAttribute
# with a value less than, or equal to the one given.
#
# Not allowed as a reply item.
} elsif ($attribute->{'Operator'} eq '<=') {
} elsif ($operator eq '<=') {
# Check for correct value
if (defined($attrVal) && $attrVal <= $tattrVal) {
$matched = 1;
}
# Operator: >=
#
# Use: Attribute >= Value
......@@ -192,13 +262,13 @@ sub checkAuthAttribute
# with a value greater than, or equal to the one given.
#
# Not allowed as a reply item.
} elsif ($attribute->{'Operator'} eq '>=') {
} elsif ($operator eq '>=') {
# Check for correct value
if (defined($attrVal) && $attrVal >= $tattrVal) {
$matched = 1;
}
# Operator: =*
#
# Use: Attribute =* Value
......@@ -206,13 +276,13 @@ sub checkAuthAttribute
# no matter what the value is.
#
# Not allowed as a reply item.
} elsif ($attribute->{'Operator'} eq '=*') {
} elsif ($operator eq '=*') {
# Check for matching value
if (defined($attrVal)) {
$matched = 1;
}
# Operator !=
#
# Use: Attribute != Value
......@@ -220,13 +290,13 @@ sub checkAuthAttribute
# request, AND does not have the given value.
#
# Not allowed as a reply item.
} elsif ($attribute->{'Operator'} eq '!=') {
} elsif ($operator eq '!=') {
# Check for correct value
if (defined($attrVal) && $attrVal ne $tattrVal) {
if (!defined($attrVal) || $attrVal ne $tattrVal) {
$matched = 1;
}
# Operator: !*
#
# Use: Attribute !* Value
......@@ -234,13 +304,13 @@ sub checkAuthAttribute
# what the value is.
#
# Not allowed as a reply item.
} elsif ($attribute->{'Operator'} eq '!*') {
} elsif ($operator eq '!*') {
# Skip if value not defined
if (!defined($attrVal)) {
$matched = 1;
}
# Operator: =~
#
# Use: Attribute =~ Value
......@@ -248,13 +318,13 @@ sub checkAuthAttribute
# This operator may only be applied to string packetAttributes.
#
# Not allowed as a reply item.
} elsif ($attribute->{'Operator'} eq '=~') {
} elsif ($operator eq '=~') {
# Check for correct value
if (defined($attrVal) && $attrVal =~ /$tattrVal/) {
$matched = 1;
}
# Operator: !~
#
# Use: Attribute !~ Value
......@@ -263,40 +333,145 @@ sub checkAuthAttribute
# what the value is.
#
# Not allowed as a reply item.
} elsif ($attribute->{'Operator'} eq '!~') {
} elsif ($operator eq '!~') {
# Check for correct value
if (defined($attrVal) && !($attrVal =~ /$tattrVal/)) {
$matched = 1;
}
# Operator: +=
#
# Use: Attribute += Value
# Always matches as a check item, and adds the current
# attribute with value to the list of configuration items.
#
# As a reply item, it has an itendtical meaning, but the
# As a reply item, it has an idendtical meaning, but the
# attribute is added to the reply items.
} elsif ($attribute->{'Operator'} eq '+=') {
# FIXME - Add to config items
$matched = 1;
} elsif ($operator eq '+=') {
# Check if we're a conditional and process
if ($attribute->{'Name'} eq "SMRadius-Evaluate") {
$matched = processConditional($server,$user,$attribute,$tattrVal);
} else {
$matched = 1;
}
# FIXME
# Operator: :=
#
# Use: Attribute := Value
# Always matches as a check item, and replaces in the configuration items any attribute of the same name.
# If no attribute of that name appears in the request, then this attribute is added.
# Always matches as a check item, and replaces in the configuration items any attribute of the same name.
} elsif ($operator eq ':=') {
# FIXME - Add or replace config items
# FIXME - Add attribute to request
# Check if we're a conditional and process
if ($attribute->{'Name'} eq "SMRadius-Evaluate") {
$matched = processConditional($server,$user,$attribute,$tattrVal);
} else {
$matched = 1;
}
# Attributes that are not defined
} else {
# Ignore
$matched = 2;
last;
}
}
# Some debugging info
if ($matched == 1) {
$server->log(LOG_DEBUG,"[ATTRIBUTES] - Attribute '".$attribute->{'Name'}."' matched");
} elsif ($matched == 2) {
$server->log(LOG_DEBUG,"[ATTRIBUTES] - Attribute '".$attribute->{'Name'}."' ignored");
} else {
$server->log(LOG_DEBUG,"[ATTRIBUTES] - Attribute '".$attribute->{'Name'}."' not matched");
}
return $matched;
}
## @fn checkAcctAttribute($server,$packetAttributes,$attribute)
# Function to check an attribute in the accounting stage
#
# @param server Server instance
# @param packetAttributes Hashref of attributes provided, eg. Those from the packet
# @param attribute Attribute to check, eg. One of the ones from the database
sub checkAcctAttribute
{
my ($server,$user,$packetAttributes,$attribute) = @_;
# Check ignore list
foreach my $ignoredAttr (@attributeCheckIgnoreList) {
# 2 = IGNORE, so return IGNORE for all ignored items
return 2 if ($attribute->{'Name'} eq $ignoredAttr);
}
# Matched & ok?
my $matched = 0;
# Figure out our attr values
my @attrValues;
if (ref($attribute->{'Value'}) eq "ARRAY") {
@attrValues = @{$attribute->{'Value'}};
} else {
@attrValues = ( $attribute->{'Value'} );
}
# Get packet attribute value
my $attrVal = $packetAttributes->{$attribute->{'Name'}};
$server->log(LOG_DEBUG,"[ATTRIBUTES] Processing CHECK attribute value ".prettyUndef($attrVal)." against: '".
$attribute->{'Name'}."' ".$attribute->{'Operator'}." '".join("','",@attrValues)."'");
# Loop with all the test attribute values
foreach my $tattrVal (@attrValues) {
# Sanitize the operator
my ($operator) = ($attribute->{'Operator'} =~ /^(?:\|\|)?(.*)$/);
# Operator: +=
#
# Use: Attribute += Value
# Always matches as a check item, and adds the current
# attribute with value to the list of configuration items.
#
# As a reply item, it has an idendtical meaning, but the
# attribute is added to the reply items.
if ($operator eq '+=') {
# Check if we're a conditional and process
if ($attribute->{'Name'} eq "SMRadius-Evaluate") {
$matched = processConditional($server,$user,$attribute,$tattrVal);
} else {
$matched = 1;
}
# FIXME
# Operator: :=
#
# As a reply item, it has an itendtical meaning, but for the reply items, instead of the request items.
} elsif ($attribute->{'Operator'} eq ':=') {
# Use: Attribute := Value
# Always matches as a check item, and replaces in the configuration items any attribute of the same name.
} elsif ($operator eq ':=') {
# FIXME - Add or replace config items
# FIXME - Add attribute to request
$matched = 1;
# Check if we're a conditional and process
if ($attribute->{'Name'} eq "SMRadius-Evaluate") {
$matched = processConditional($server,$user,$attribute,$tattrVal);
} else {
$matched = 1;
}
# Attributes that are not defined
} else {
# Ignore
......@@ -305,7 +480,7 @@ sub checkAuthAttribute
}
}
# Some debugging info
# Some debugging info
if ($matched == 1) {
$server->log(LOG_DEBUG,"[ATTRIBUTES] - Attribute '".$attribute->{'Name'}."' matched");
} elsif ($matched == 2) {
......@@ -330,7 +505,7 @@ sub setReplyAttribute
{
my ($server,$attributes,$attribute) = @_;
# Check ignore list
foreach my $ignoredAttr (@attributeReplyIgnoreList) {
# 2 = IGNORE, so return IGNORE for all ignored items
......@@ -343,11 +518,11 @@ sub setReplyAttribute
@attrValues = @{$attribute->{'Value'}};
} else {
@attrValues = ( $attribute->{'Value'} );
}
}
$server->log(LOG_DEBUG,"[ATTRIBUTES] Processing REPLY attribute: '".
$attribute->{'Name'}."' ".$attribute->{'Operator'}." '".join("','",@attrValues)."'");
# Operator: =
#
......@@ -358,7 +533,7 @@ sub setReplyAttribute
#
# As a reply item, it means "add the item to the reply list, but only if there is
# no other item of the same attribute.
if ($attribute->{'Operator'} eq '=') {
# If item does not exist
if (!defined($attributes->{$attribute->{'Name'}})) {
......@@ -368,42 +543,41 @@ sub setReplyAttribute
@{$attributes->{$attribute->{'Name'}}} = @attrValues;
}
# Operator: :=
#
# Use: Attribute := Value
# Always matches as a check item, and replaces in the configuration items any attribute of the same name.
# Always matches as a check item, and replaces in the configuration items any attribute of the same name.
# If no attribute of that name appears in the request, then this attribute is added.
#
# As a reply item, it has an itendtical meaning, but for the reply items, instead of the request items.
# As a reply item, it has an idendtical meaning, but for the reply items, instead of the request items.
} elsif ($attribute->{'Operator'} eq ':=') {
# Overwrite
$server->log(LOG_DEBUG,"[ATTRIBUTES] - Attribute '".$attribute->{'Name'}.
"' setting attribute value to '".join("','",@attrValues)."'");
@{$attributes->{$attribute->{'Name'}}} = @attrValues;
# Operator: +=
#
# Use: Attribute += Value
# Always matches as a check item, and adds the current
# attribute with value to the list of configuration items.
#
# As a reply item, it has an itendtical meaning, but the
# As a reply item, it has an idendtical meaning, but the
# attribute is added to the reply items.
} elsif ($attribute->{'Operator'} eq '+=') {
# Then add
$server->log(LOG_DEBUG,"[ATTRIBUTES] - Attribute '".$attribute->{'Name'}.
"' appending values '".join("','",@attrValues)."'");
push(@{$attributes->{$attribute->{'Name'}}},@attrValues);
# Attributes that are not defined
} else {
# Ignore and b0rk out
# Ignore invalid operator
$server->log(LOG_NOTICE,"[ATTRIBUTES] - Attribute '".$attribute->{'Name'}."' ignored, invalid operator?");
last;
}
return;
......@@ -422,7 +596,7 @@ sub setReplyVAttribute
{
my ($server,$attributes,$attribute) = @_;
# Check ignore list
foreach my $ignoredAttr (@attributeVReplyIgnoreList) {
# 2 = IGNORE, so return IGNORE for all ignored items
......@@ -438,11 +612,11 @@ sub setReplyVAttribute
@attrValues = @{$attribute->{'Value'}};
} else {
@attrValues = ( $attribute->{'Value'} );
}
}
$server->log(LOG_DEBUG,"[VATTRIBUTES] Processing REPLY attribute: '".
$server->log(LOG_DEBUG,"[VATTRIBUTES] Processing REPLY vattribute: '".
$attribute->{'Name'}."' ".$attribute->{'Operator'}." '".join("','",@attrValues)."'");
# Operator: =
#
......@@ -453,7 +627,7 @@ sub setReplyVAttribute
#
# As a reply item, it means "add the item to the reply list, but only if there is
# no other item of the same attribute.
if ($attribute->{'Operator'} eq '=') {
# If item does not exist
if (!defined($attributes->{$attribute->{'Vendor'}}->{$attribute->{'Name'}})) {
......@@ -463,37 +637,37 @@ sub setReplyVAttribute
@{$attributes->{$attribute->{'Vendor'}}->{$attribute->{'Name'}}} = @attrValues;
}
# Operator: :=
#
# Use: Attribute := Value
# Always matches as a check item, and replaces in the configuration items any attribute of the same name.
# Always matches as a check item, and replaces in the configuration items any attribute of the same name.
# If no attribute of that name appears in the request, then this attribute is added.
#
# As a reply item, it has an itendtical meaning, but for the reply items, instead of the request items.
# As a reply item, it has an idendtical meaning, but for the reply items, instead of the request items.
} elsif ($attribute->{'Operator'} eq ':=') {
# Overwrite
$server->log(LOG_DEBUG,"[VATTRIBUTES] - Attribute '".$attribute->{'Name'}.
"' setting attribute value to '".join("','",@attrValues)."'");
@{$attributes->{$attribute->{'Vendor'}}->{$attribute->{'Name'}}} = @attrValues;
# Operator: +=
#
# Use: Attribute += Value
# Always matches as a check item, and adds the current
# attribute with value to the list of configuration items.
#
# As a reply item, it has an itendtical meaning, but the
# As a reply item, it has an idendtical meaning, but the
# attribute is added to the reply items.
} elsif ($attribute->{'Operator'} eq '+=') {
# Then add
$server->log(LOG_DEBUG,"[VATTRIBUTES] - Attribute '".$attribute->{'Name'}.
"' appending values '".join("','",@attrValues)."'");
push(@{$attributes->{$attribute->{'Vendor'}}->{$attribute->{'Name'}}},@attrValues);
# Attributes that are not defined
} else {
# Ignore and b0rk out
......@@ -507,7 +681,7 @@ sub setReplyVAttribute
## @fn processConfigAttribute($server,$packetAttributes,$attribute)
## @fn processConfigAttribute($server,$user,$attribute)
# Function to process a configuration attribute
#
# @param server Server instance
......@@ -515,11 +689,13 @@ sub setReplyVAttribute
# @param attribute Attribute to process, eg. One of the ones from the database
sub processConfigAttribute
{
my ($server,$configAttributes,$attribute) = @_;
my ($server,$user,$attribute) = @_;
# Make things easier?
my $configAttributes = $user->{'ConfigAttributes'};
# Matched & ok?
my $matched = 0;
# Did we get processed?
my $processed = 0;
# Figure out our attr values
my @attrValues;
......@@ -527,41 +703,42 @@ sub processConfigAttribute
@attrValues = @{$attribute->{'Value'}};
} else {
@attrValues = ( $attribute->{'Value'} );
}
}
$server->log(LOG_DEBUG,"[ATTRIBUTES] Processing CONFIG attribute: '".$attribute->{'Name'}."' ".
$attribute->{'Operator'}." '".join("','",@attrValues)."'");
# Operator: +=
#
# Use: Attribute += Value
# Always matches as a check item, and adds the current
# attribute with value to the list of configuration items.
#
# As a reply item, it has an itendtical meaning, but the
# As a reply item, it has an idendtical meaning, but the
# attribute is added to the reply items.
if ($attribute->{'Operator'} eq '+=') {
$server->log(LOG_DEBUG,"[ATTRIBUTES] Operator '+=' triggered: Adding item to configuration items.");
push(@{$configAttributes->{$attribute->{'Name'}}},@attrValues);
$processed = 1;
# Operator: :=
#
# Use: Attribute := Value
# Always matches as a check item, and replaces in the configuration items any attribute of the same name.
# Always matches as a check item, and replaces in the configuration items any attribute of the same name.
# If no attribute of that name appears in the request, then this attribute is added.
#
# As a reply item, it has an itendtical meaning, but for the reply items, instead of the request items.
# As a reply item, it has an idendtical meaning, but for the reply items, instead of the request items.
} elsif ($attribute->{'Operator'} eq ':=') {
$server->log(LOG_DEBUG,"[ATTRIBUTES] Operator ':=' triggered: Adding or replacing item in configuration items.");
@{$configAttributes->{$attribute->{'Name'}}} = @attrValues;
$processed = 1;
# Operators that are not defined
} else {
# Ignore
$server->log(LOG_DEBUG,"[ATTRIBUTES] - Attribute '".$attribute->{'Name'}."' ignored");
}
# If we got procsessed output some debug
if ($processed) {
$server->log(LOG_DEBUG,"[ATTRIBUTES] Processed CONFIG attribute: '".$attribute->{'Name'}."' ".
$attribute->{'Operator'}." '".join("','",@attrValues)."'");
}
return $processed;
}
......@@ -587,5 +764,113 @@ sub getAttributeValue
}
## @fn addAttributeConditionalVariable($user,$name,$value)
# Function that adds a conditional variable
#
# @param user User hash
# @param name Variable name
# @param value Variable value
sub addAttributeConditionalVariable
{
my ($user,$name,$value) = @_;
$user->{'AttributeConditionalVariables'}->{$name} = [ $value ];
return;
}
## @fn processConditional($server,$user,$attribute,$attrVal)
# This function processes a attribute conditional
#
# @param server Server hash
# @param user User hash
# @param attribute Attribute hash to process
# @param attrVal Current value we need to process
sub processConditional
{
my ($server,$user,$attribute,$attrVal) = @_;
# Split off expression
# NK: This probably needs a bit of work
my ($condition,$onTrue,$onFalse) = ($attrVal =~ /^([^\?]*)(?:\?\s*((?:\S+)?[^:]*)(?:\:\s*(.*))?)?$/);
# If there is no condition we cannot really continue?
if (!defined($condition)) {
$server->log(LOG_WARN,"[ATTRIBUTES] Conditional '$attrVal' cannot be parsed");
return 1;
}
$server->log(LOG_DEBUG,"[ATTRIBUTES] Conditional parsed ".$attribute->{'Name'}." => if ($condition) then {".
( $onTrue ? $onTrue : "-undef-")."} else {".( $onFalse ? $onFalse : "-undef-")."}");
# Create the environment
my @error;
my $mathEnv = Math::Expression->new(
'PrintErrFunc' => sub { @error = @_ },
'VarHash' => $user->{'AttributeConditionalVariables'}
);
# Parse and create math tree
my $mathTree = $mathEnv->Parse($condition);
# Check for error
if (@error) {
my $errorStr = sprintf($error[0],$error[1]);
$server->log(LOG_WARN,"[ATTRIBUTES] Conditional '$condition' in '$attrVal' does not parse: $errorStr");
return 1;
}
# Evaluate tree
my $res = $mathEnv->Eval($mathTree);
if (!defined($res)) {
$server->log(LOG_WARN,"[ATTRIBUTES] Conditional '$condition' in '$attrVal' does not evaluate");
return 1;
}
# Check result
# If we have a onTrue or onFalse we will return "Matched = True"
# If we don't have an onTrue or onFalse we will return the result of the $condition
my $attribStr;
if ($res && defined($onTrue)) {
$attribStr = $onTrue;
$res = 1;
} elsif (!$res && defined($onFalse)) {
$attribStr = $onFalse;
$res = 1;
} elsif (defined($onTrue) || defined($onFalse)) {
$res = 1;
}
$server->log(LOG_DEBUG,"[ATTRIBUTES] - Evaluated to '$res' returning '".(defined($attribStr) ? $attribStr : "-undef-")."'");
# Loop with attributes:
# We only get here if $res is set to 1 above, if its only a conditional with no onTrue & onFalse
# Then attribStr will be unef
if ($res && defined($attribStr)) {
# Sanitize the output
$attribStr =~ s/^\s*//;
$attribStr =~ s/\s*$//;
foreach my $rawAttr (split(/;/,$attribStr)) {
# Split off attribute string: name = value
my ($attrName,$attrVal) = ($rawAttr =~ /^\s*([^=]+)=\s*(.*)/);
# Build attribute
my $attribute = {
'Name' => $attrName,
'Operator' => ':=',
'Value' => $attrVal
};
# Add attribute
addAttribute($server,$user,$attribute);
}
}
return $res;
}
1;
# vim: ts=4
# Radius client
# Copyright (C) 2007-2019, AllWorldIT
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
package smradius::client;
use strict;
use warnings;
use base qw(AWITPT::Object);
use Getopt::Long qw( GetOptionsFromArray );
use IO::Select;
use IO::Socket;
use smradius::version;
use smradius::Radius::Packet;
# Check Config::IniFiles is instaslled
if (!eval {require Config::IniFiles; 1;}) {
print STDERR "You're missing Config::IniFiles, try 'apt-get install libconfig-inifiles-perl'\n";
exit 1;
}
# Run the client
sub run
{
my ($self,@methodArgs) = @_;
# Instantiate if we're not already instantiated
$self = $self->new() if (!ref($self));
# The hash we're going to return
my $ret = { };
print(STDERR "SMRadClient v".VERSION." - Copyright (c) 2007-2019, AllWorldIT\n");
print(STDERR "\n");
# Set defaults
my $cfg;
$cfg->{'config_file'} = "/etc/smradiusd.conf";
# Grab runtime arguments
my @runArgs = @methodArgs ? @methodArgs : @ARGV;
# Parse command line params
my $cmdline;
%{$cmdline} = ();
if (!GetOptionsFromArray(
\@runArgs,
\%{$cmdline},
"config:s",
"raddb:s",
"listen:s",
"help",
)) {
print(STDERR "ERROR: Error parsing commandline arguments");
return 1;
}
# Check for some args
if ($cmdline->{'help'}) {
displayHelp();
return 0;
}
# Make sure we only have 2 additional args
if (@runArgs < 3) {
print(STDERR "ERROR: Invalid number of arguments\n");
displayHelp();
return 1;
}
if (!defined($cmdline->{'raddb'}) || $cmdline->{'raddb'} eq "") {
print(STDERR "ERROR: No raddb directory specified!\n");
displayHelp();
return 1;
}
# Get variables we need
my $server = shift(@runArgs);
my $type = shift(@runArgs);
$self->{'secret'} = shift(@runArgs);
# Validate type
if (!defined($type) || ( $type ne "acct" && $type ne "auth" && $type ne "disconnect")) {
print(STDERR "ERROR: Invalid packet type specified!\n");
displayHelp();
return 1;
}
print(STDERR "\n");
# Time to start loading the dictionary
print(STDERR "Loading dictionaries...");
my $raddb = smradius::Radius::Dictionary->new();
# Look for files in the dir
my $DIR;
if (!opendir($DIR, $cmdline->{'raddb'})) {
print(STDERR "ERROR: Cannot open '".$cmdline->{'raddb'}."': $!");
return 1;
}
my @raddb_files = readdir($DIR);
# And load the dictionary
foreach my $df (@raddb_files) {
my $df_fn = $cmdline->{'raddb'}."/$df";
# Load dictionary
if (!$raddb->readfile($df_fn)) {
print(STDERR "Failed to load dictionary '$df_fn': $!");
}
print(STDERR ".");
}
print(STDERR "\n");
# Decide what type of packet this is
my $port;
my $pkt_code;
if ($type eq "acct") {
$port = 1813;
$pkt_code = "Accounting-Request";
} elsif ($type eq "auth") {
$port = 1812;
$pkt_code = "Access-Request";
} elsif ($type eq "disconnect") {
$port = 1813;
$pkt_code = "Disconnect-Request";
}
print(STDERR "\nRequest:\n");
printf(STDERR " > Secret => '%s'\n",$self->{'secret'});
# Build packet
$self->{'packet'} = smradius::Radius::Packet->new($raddb);
$self->{'packet'}->set_code($pkt_code);
# Generate identifier
my $ident = int(rand(32768));
$self->{'packet'}->set_identifier($ident);
print(STDERR " > Identifier: $ident\n");
# Generate authenticator number
my $authen = int(rand(32768));
$self->{'packet'}->set_authenticator($authen);
print(STDERR " > Authenticator: $ident\n");
# Pull in attributes from STDIN if we're not being called as a function
if (!@runArgs) {
while (my $line = <STDIN>) {
$self->addAttributesFromString($line);
}
}
# Pull in attributes from commandline
while (my $line = shift(@runArgs)) {
$self->addAttributesFromString($line);
}
# Create UDP packet
my $udp_packet = $self->{'packet'}->pack();
# Create socket to send packet out on
my $sockTimeout = "10"; # 10 second timeout
my $sock = IO::Socket::INET->new(
PeerAddr => $server,
PeerPort => $port,
Type => SOCK_DGRAM,
Proto => 'udp',
Timeout => $sockTimeout,
);
if (!$sock) {
print(STDERR "ERROR: Failed to create socket\n");
return 1;
}
my $sock2;
# Check if we must listen on another IP/port
if (defined($cmdline->{'listen'}) && $cmdline->{'listen'} ne "") {
print(STDERR "Creating second socket\n");
# Check the details we were provided
my ($localAddr,$localPort) = split(/:/,$cmdline->{'listen'});
if (!defined($localPort)) {
print(STDERR "ERROR: The format for --listen is IP:Port\n");
return 1;
}
$sock2 = IO::Socket::INET->new(
LocalAddr => $localAddr,
LocalPort => $localPort,
Type => SOCK_DGRAM,
Proto => 'udp',
Timeout => $sockTimeout,
);
if (!$sock2) {
print(STDERR "ERROR: Failed to create second socket\n");
return 1;
}
}
# Check if we sent the packet...
if (!$sock->send($udp_packet)) {
print(STDERR "ERROR: Failed to send data on socket\n");
return 1;
}
# And time for the response
print(STDERR "\nResponse:\n");
# Once sent, we need to get a response back
my $rsock = IO::Select->new($sock);
if (!$rsock) {
print(STDERR "ERROR: Failed to select response data on socket\n");
return 1;
}
# Check if we can read a response after the select()
if (!$rsock->can_read($sockTimeout)) {
print(STDERR "ERROR: Failed to receive response data on socket\n");
return 1;
}
# Read packet
$sock->recv($udp_packet, 65536);
if (!$udp_packet) {
print(STDERR "ERROR: Receive response data failed on socket: $!\n");
return 1;
}
# Parse packet
my $pkt = smradius::Radius::Packet->new($raddb,$udp_packet);
print(STDERR " > Authenticated: ". (defined(auth_req_verify($udp_packet,$self->{'secret'},$authen)) ? "yes" : "no") ."\n");
print(STDERR $pkt->str_dump());
# Setup response
$ret->{'request'} = $self->hashedPacket($self->{'packet'});
$ret->{'response'} = $self->hashedPacket($pkt);
my $udp_packet2;
if (defined($sock2)) {
my $rsock2 = IO::Select->new($sock2);
if (!$rsock2) {
print(STDERR "ERROR: Failed to select response data on socket2\n");
return 1;
}
# Check if we can read a response after the select()
if (!$rsock2->can_read($sockTimeout)) {
print(STDERR "ERROR: Failed to receive response data on socket2\n");
return 1;
}
# Read packet
my $udp_packet2;
$sock2->recv($udp_packet2, 65536);
if (!$udp_packet2) {
print(STDERR "ERROR: Receive response data failed on socket2: $!\n");
return 1;
}
my $pkt2 = smradius::Radius::Packet->new($raddb,$udp_packet2);
print(STDERR $pkt2->str_dump());
# Save the packet we got
$ret->{'listen'}->{'response'} = $self->hashedPacket($pkt2);
}
# If we were called as a function, return hashed version of the response packet
if (@methodArgs) {
return $ret;
}
return 0;
}
# Return a hashed version of the packet
sub hashedPacket
{
my ($self,$pkt) = @_;
my $res = {};
$res->{'code'} = $pkt->code();
$res->{'identifier'} = $pkt->identifier();
foreach my $attrName (sort $pkt->attributes()) {
my $attrVal = $pkt->rawattr($attrName);
$res->{'attributes'}->{$attrName} = $attrVal;
}
foreach my $attrVendor ($pkt->vendors()) {
foreach my $attrName ($pkt->vsattributes($attrVendor)) {
$res->{'vattributes'}->{$attrVendor}->{$attrName} = $pkt->vsattr($attrVendor,$attrName);
}
}
return $res;
}
# Allow adding attribute from a string
sub addAttributesFromString
{
my ($self,$line) = @_;
# Remove EOL
chomp($line);
# Split on , and newline
my @rawAttributes = split(/[,\n]+/,$line);
foreach my $attr (@rawAttributes) {
# Pull off attribute name & value
my ($name,$value) = ($attr =~ /\s*(\S+)\s*=\s?(.+)/);
$self->addAttribute($name,$value);
}
return;
}
# Add attribute to packet
sub addAttribute
{
my ($self,$name,$value) = @_;
# Add to packet
print(STDERR " > Adding '$name' => '$value'\n");
if ($name eq "User-Password") {
$self->{'packet'}->set_password($value,$self->{'secret'});
} else {
$self->{'packet'}->set_attr($name,$value);
}
return;
}
# Display help
sub displayHelp {
print(STDERR<<EOF);
Usage: $0 [args] <server> <acct|auth|disconnect> <secret> [ATTR=VALUE,...]
--raddb=<DIR> Directory where the radius dictionary files are
EOF
return;
}
1;
# vim: ts=4
# SMRadius config information
# Copyright (C) 2007-2015, AllWorldIT
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
## @class smradius::config
# Configuration handling class
package smradius::config;
use strict;
use warnings;
# Exporter stuff
use base qw(Exporter);
our @EXPORT = qw(
);
our @EXPORT_OK = qw(
);
use AWITPT::Util;
use smradius::logging;
# Our vars
my $config;
## @fn Init($server)
# Initialize this module with a server object
#
# @param server Server object we need to setup
sub Init
{
my $server = shift;
# Setup configuration
$config = $server->{'inifile'};
# Setup database config
my $db;
$db->{'DSN'} = $config->{'database'}{'dsn'};
$db->{'Username'} = $config->{'database'}{'username'};
$db->{'Password'} = $config->{'database'}{'password'};
$db->{'enabled'} = 0;
# Check we have all the config we need
if (!defined($db->{'DSN'})) {
$server->log(LOG_NOTICE,"smradius/config.pm: No 'DSN' defined in config file for 'database'");
}
$server->{'smradius'}{'database'} = $db;
# Setup event timezone config
if (defined($config->{'server'}{'event_timezone'})) {
$server->{'smradius'}{'event_timezone'} = $config->{'server'}{'event_timezone'};
} else {
$server->{'smradius'}{'event_timezone'} = "GMT";
}
# Should we use the packet timestamp?
if (defined($config->{'radius'}{'use_packet_timestamp'})) {
if (defined(my $val = isBoolean($config->{'radius'}{'use_packet_timestamp'}))) {
$server->{'smradius'}{'use_packet_timestamp'} = $val;
} else {
$server->log(LOG_NOTICE,"smradius/config.pm: Value for 'use_packet_timestamp' is invalid");
}
} else {
$server->{'smradius'}{'use_packet_timestamp'} = 0;
}
# Should we use abuse prevention?
if (defined($config->{'radius'}{'use_abuse_prevention'})) {
if (defined(my $val = isBoolean($config->{'radius'}{'use_abuse_prevention'}))) {
$server->{'smradius'}{'use_abuse_prevention'} = $val;
} else {
$server->log(LOG_NOTICE,"smradius/config.pm: Value for 'use_abuse_prevention' is invalid");
}
} else {
$server->{'smradius'}{'use_abuse_prevention'} = 0;
}
if (defined($config->{'radius'}{'access_request_abuse_threshold'})) {
if ($config->{'radius'}{'access_request_abuse_threshold'} =~ /^[1-9][0-9]*$/i) {
$server->{'smradius'}{'access_request_abuse_threshold'} = $config->{'radius'}{'access_request_abuse_threshold'};
} else {
$server->log(LOG_NOTICE,"smradius/config.pm: Value for 'access_request_abuse_threshold' is invalid");
}
} else {
$server->{'smradius'}{'access_request_abuse_threshold'} = 10;
}
if (defined($config->{'radius'}{'accounting_request_abuse_threshold'})) {
if ($config->{'radius'}{'accounting_request_abuse_threshold'} =~ /^[1-9][0-9]*$/i) {
$server->{'smradius'}{'accounting_request_abuse_threshold'} = $config->{'radius'}{'accounting_request_abuse_threshold'};
} else {
$server->log(LOG_NOTICE,"smradius/config.pm: Value for 'accounting_request_abuse_threshold' is invalid");
}
} else {
$server->{'smradius'}{'accounting_request_abuse_threshold'} = 5;
}
$server->log(LOG_NOTICE,"smradius/config.pm: Using ". ( $server->{'smradius'}{'use_packet_timestamp'} ? 'packet' : 'server' ) ." timestamp");
$server->log(LOG_NOTICE,"smradius/config.pm: Using timezone '".$server->{'smradius'}{'event_timezone'}."'");
$server->log(LOG_NOTICE,"smradius/config.pm: Abuse prevention ".( $server->{'smradius'}{'use_abuse_prevention'} ?
'active (access-threshold = '.$server->{'smradius'}{'access_request_abuse_threshold'}.
', accounting-threshold = '.$server->{'smradius'}{'accounting_request_abuse_threshold'}.')'
: 'inactive'));
return;
}
## @fn getConfig
# Get the config hash
#
# @return Hash ref of all our config items
sub getConfig
{
return $config;
}
1;
# vim: ts=4
# SMRadius Constants
# Copyright (C) 2007-2009, AllWorldIT
# Copyright (C) 2007-2015, AllWorldIT
#
# 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
......@@ -20,31 +20,36 @@
## @class smradius::constants
# SMRadius constants package
package smradius::constants;
use base qw(Exporter);
use strict;
use warnings;
# Exporter stuff
require Exporter;
our (@ISA,@EXPORT,@EXPORT_OK);
@ISA = qw(Exporter);
our (@EXPORT,@EXPORT_OK);
@EXPORT = qw(
RES_OK
RES_ERROR
MOD_RES_ACK
MOD_RES_NACK
MOD_RES_SKIP
GIGAWORD_VALUE
);
@EXPORT_OK = ();
use constant {
RES_OK => 0,
RES_ERROR => -1,
RES_OK => 0,
RES_ERROR => -1,
MOD_RES_SKIP => 0,
MOD_RES_ACK => 1,
MOD_RES_NACK => 2,
MOD_RES_SKIP => 0,
MOD_RES_ACK => 1,
MOD_RES_NACK => 2,
GIGAWORD_VALUE => 2**32,
};
......
#!/usr/bin/perl
# Radius daemon
# Copyright (C) 2007-2009, AllWorldIT
#
# Copyright (C) 2007-2019, AllWorldIT
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
package smradius::daemon;
use strict;
use warnings;
# Set library directory
use lib qw(
../ ./
smradius/modules/authentication
smradius/modules/userdb
smradius/modules/accounting
smradius/modules/features
smradius/modules/config
);
package radiusd;
# Check if we have Net::Server::PreFork installed
if (!eval {require Net::Server::PreFork; 1;}) {
print STDERR "You're missing Net::Server::PreFork, try 'apt-get install libnet-server-perl'\n";
exit 1;
}
# Check Config::IniFiles is instaslled
if (!eval {require Config::IniFiles; 1;}) {
print STDERR "You're missing Config::IniFiles, try 'apt-get install libconfig-inifiles-perl'\n";
exit 1;
}
# Check DateTime is installed
if (!eval {require DateTime; 1;}) {
print STDERR "You're missing DateTime, try 'apt-get install libdatetime-perl'\n";
exit 1;
}
# Check Crypt::DES is installed
if (!eval {require Crypt::DES; 1;}) {
print STDERR "You're missing DateTime, try 'apt-get install libcrypt-des-perl'\n";
exit 1;
}
# Check Crypt::RC4 is installed
if (!eval {require Crypt::RC4; 1;}) {
print STDERR "You're missing Crypt::RC4, try 'apt-get install libcrypt-rc4-perl'\n";
exit 1;
}
# Check Digest::MD4 is installed
if (!eval {require Digest::MD4; 1;}) {
print STDERR "You're missing Digest::MD4, try 'apt-get install libdigest-md4-perl'\n";
exit 1;
}
# Check Digest::SHA is installed
if (!eval {require Digest::SHA; 1;}) {
print STDERR "You're missing Digest::SHA, try 'apt-get install libdigest-sha-perl'\n";
exit 1;
}
# Check Date::Parse is installed
if (!eval {require Date::Parse; 1;}) {
print STDERR "You're missing TimeDate, try 'apt-get install libtimedate-perl'\n";
exit 1;
}
# Check Cache::FastMmap is installed
if (!eval {require Cache::FastMmap; 1;}) {
print STDERR "You're missing DateTime, try 'apt-get install libcache-fastmmap-perl'\n";
exit 1;
} else {
eval {use AWITPT::Cache;};
}
# Check MIME::Lite is installed
if (!eval {require MIME::Lite; 1;}) {
print STDERR "You're missing MIME::Lite, try 'apt-get install libmime-lite-perl'\n";
exit 1;
}
## no critic (BuiltinFunctions::ProhibitStringyEval)
eval qq{
use base qw(Net::Server::PreFork);
};
## use critic
use base qw(Net::Server::PreFork);
use Config::IniFiles;
use DateTime;
use Getopt::Long;
use Getopt::Long qw( GetOptionsFromArray );
use Socket;
use Sys::Syslog;
use Time::HiRes qw( gettimeofday tv_interval );
use AWITPT::DB::DBLayer;
use AWITPT::Util qw( booleanize );
use smradius::Radius::Packet;
use smradius::version;
use smradius::constants;
use smradius::daemon::request;
use smradius::logging;
use smradius::config;
use smradius::dbilayer;
use smradius::cache;
use smradius::util;
use smradius::attributes;
use Radius::Packet;
use Socket;
......@@ -71,34 +131,42 @@ sub configure {
# Set defaults
my $cfg;
$cfg->{'config_file'} = "/etc/smradiusd.conf";
$cfg->{'cache_file'} = '/var/run/smradius/cache';
$server->{'timeout'} = 120;
$server->{'background'} = "yes";
$server->{'pid_file'} = "/var/run/smradiusd.pid";
$server->{'pid_file'} = "/var/run/smradius/smradiusd.pid";
$server->{'log_level'} = 2;
$server->{'log_file'} = "/var/log/smradiusd.log";
$server->{'log_file'} = "/var/log/smradius/smradiusd.log";
$server->{'host'} = "*";
$server->{'port'} = [ 1812, 1813 ];
$server->{'proto'} = 'udp';
$server->{'min_servers'} = 4;
$server->{'min_spare_servers'} = 4;
$server->{'max_spare_servers'} = 12;
$server->{'max_servers'} = 25;
$server->{'max_requests'} = 1000;
# Work out runtime arguments
my @runArgs = @{$server->{'_run_args'}} ? @{$server->{'_run_args'}} : @ARGV;
# Parse command line params
my $cmdline;
%{$cmdline} = ();
GetOptions(
if (!GetOptionsFromArray(
\@runArgs,
\%{$cmdline},
"help",
"config:s",
"debug",
"fg",
) or die "Error parsing commandline arguments";
)) {
print(STDERR "ERROR: Error parsing commandline arguments");
return 1;
}
# Check for some args
if ($cmdline->{'help'}) {
$self->displayHelp();
......@@ -112,7 +180,7 @@ sub configure {
if (! -f $cfg->{'config_file'}) {
die("No configuration file '".$cfg->{'config_file'}."' found!\n");
}
# Use config file, ignore case
tie my %inifile, 'Config::IniFiles', (
-file => $cfg->{'config_file'},
......@@ -120,7 +188,7 @@ sub configure {
) or die "Failed to open config file '".$cfg->{'config_file'}."': $!";
# Copy config
my %config = %inifile;
untie(%inifile);
#untie(%inifile);
# Pull in params for the server
my @server_params = (
......@@ -128,15 +196,15 @@ sub configure {
# 'port', - We don't want to override this do we?
'host',
'cidr_allow', 'cidr_deny',
'pid_file',
'pid_file',
'user', 'group',
'timeout',
'background',
'min_servers',
'min_servers',
'min_spare_servers',
'max_spare_servers',
'max_servers',
'max_requests',
'max_requests'
);
foreach my $param (@server_params) {
$server->{$param} = $config{'server'}{$param} if (defined($config{'server'}{$param}));
......@@ -173,103 +241,141 @@ sub configure {
$cfg->{'logging'}{$detail} = 1;
}
}
#
# System plugins
# System modules
#
my @system_params = (
'plugins',
);
my $system;
foreach my $param (@system_params) {
$system->{$param} = $config{'system'}{$param} if (defined($config{'system'}{$param}));
}
if (!defined($system->{'plugins'})) {
$self->log(LOG_ERR,"[SMRADIUS] System configuration error: System plugins not found");
exit 1;
if (ref($config{'system'}{'modules'}) eq "ARRAY") {
foreach my $module (@{$config{'system'}{'modules'}}) {
$module =~ s/\s+//g;
# Skip comments
next if ($module =~ /^#/);
$module = "system/$module";
push(@{$cfg->{'module_list'}},$module);
}
} else {
my @moduleList = split(/\s+/,$config{'system'}{'modules'});
foreach my $module (@moduleList) {
# Skip comments
next if ($module =~ /^#/);
$module = "system/$module";
push(@{$cfg->{'module_list'}},$module);
}
}
#
# Authentication plugins
# Feature modules
#
my @auth_params = (
'mechanisms',
'users',
);
my $auth;
foreach my $param (@auth_params) {
$auth->{$param} = $config{'authentication'}{$param} if (defined($config{'authentication'}{$param}));
}
if (!defined($auth->{'users'})) {
$self->log(LOG_ERR,"[SMRADIUS] Authentication configuration error: Userdb plugins not found");
exit 1;
if (ref($config{'features'}{'modules'}) eq "ARRAY") {
foreach my $module (@{$config{'features'}{'modules'}}) {
$module =~ s/\s+//g;
# Skip comments
next if ($module =~ /^#/);
$module = "features/$module";
push(@{$cfg->{'module_list'}},$module);
}
} else {
my @moduleList = split(/\s+/,$config{'features'}{'modules'});
foreach my $module (@moduleList) {
# Skip comments
next if ($module =~ /^#/);
$module = "features/$module";
push(@{$cfg->{'module_list'}},$module);
}
}
#
# Accounting plugins
# Authentication modules
#
my @acct_params = (
'plugins',
);
my $acct;
foreach my $param (@acct_params) {
$acct->{$param} = $config{'accounting'}{$param} if (defined($config{'accounting'}{$param}));
if (ref($config{'authentication'}{'mechanisms'}) eq "ARRAY") {
foreach my $module (@{$config{'authentication'}{'mechanisms'}}) {
$module =~ s/\s+//g;
# Skip comments
next if ($module =~ /^#/);
$module = "authentication/$module";
push(@{$cfg->{'module_list'}},$module);
}
} else {
my @moduleList = split(/\s+/,$config{'authentication'}{'mechanisms'});
foreach my $module (@moduleList) {
# Skip comments
next if ($module =~ /^#/);
$module = "authentication/$module";
push(@{$cfg->{'module_list'}},$module);
}
}
if (!defined($acct->{'plugins'})) {
$self->log(LOG_ERR,"[SMRADIUS] Accounting configuration error: Plugins not found");
exit 1;
if (ref($config{'authentication'}{'users'}) eq "ARRAY") {
foreach my $module (@{$config{'authentication'}{'users'}}) {
$module =~ s/\s+//g;
# Skip comments
next if ($module =~ /^#/);
$module = "userdb/$module";
push(@{$cfg->{'module_list'}},$module);
}
} else {
my @moduleList = split(/\s+/,$config{'authentication'}{'users'});
foreach my $module (@moduleList) {
# Skip comments
next if ($module =~ /^#/);
$module = "userdb/$module";
push(@{$cfg->{'module_list'}},$module);
}
}
#
# Feature plugins
# Accounting modules
#
my $features;
$features->{'plugins'} = [ ];
$features->{'plugins'} = $config{'features'}{'plugins'} if (defined($config{'features'}{'plugins'}));
if (ref($config{'accounting'}{'modules'}) eq "ARRAY") {
foreach my $module (@{$config{'accounting'}{'modules'}}) {
$module =~ s/\s+//g;
# Skip comments
next if ($module =~ /^#/);
$module = "accounting/$module";
push(@{$cfg->{'module_list'}},$module);
}
} else {
my @moduleList = split(/\s+/,$config{'accounting'}{'modules'});
foreach my $module (@moduleList) {
# Skip comments
next if ($module =~ /^#/);
$module = "accounting/$module";
push(@{$cfg->{'module_list'}},$module);
}
}
#
# Dictionary configuration
#
my @dictionary_params = (
'load',
);
my $dictionary;
foreach my $param (@dictionary_params) {
$dictionary->{$param} = $config{'dictionary'}{$param} if (defined($config{'dictionary'}{$param}));
}
if (!defined($dictionary->{'load'})) {
$self->log(LOG_ERR,"[SMRADIUS] Dictionary configuration error: 'load' not found");
exit 1;
}
# Split off dictionaries to load
foreach my $fn (@{$dictionary->{'load'}}) {
$fn =~ s/\s+//g;
if (ref($config{'dictionary'}->{'load'}) eq "ARRAY") {
foreach my $dict (@{$config{'dictionary'}->{'load'}}) {
$dict =~ s/\s+//g;
# Skip comments
next if ($dict =~ /^#/);
push(@{$cfg->{'dictionary_list'}},$dict);
}
} else {
my @dictList = split(/\s+/,$config{'dictionary'}->{'load'});
foreach my $dict (@dictList) {
# Skip comments
next if ($dict =~ /^#/);
push(@{$cfg->{'dictionary_list'}},$dict);
}
}
$cfg->{'authentication'} = $auth;
$cfg->{'dictionary'} = $dictionary;
$cfg->{'plugins'} = [
@{$auth->{'mechanisms'}},
@{$auth->{'users'}},
@{$acct->{'plugins'}},
@{$features->{'plugins'}},
@{$system->{'plugins'}}
];
# Clean up plugins
foreach my $plugin (@{$cfg->{'plugins'}}) {
$plugin =~ s/\s+//g;
# Check if the user specified a cache_file in the config
if (defined($config{'server'}{'cache_file'})) {
$cfg->{'cache_file'} = $config{'server'}{'cache_file'};
}
# Save our config and stuff
$self->{'config'} = $cfg;
$self->{'cmdline'} = $cmdline;
$self->{'inifile'} = \%config;
return;
}
......@@ -280,46 +386,60 @@ sub post_configure_hook {
my $config = $self->{'config'};
$self->log(LOG_NOTICE,"[SMRADIUS] SMRadius - v$VERSION");
# Init config
$self->log(LOG_NOTICE,"[SMRADIUS] Initializing configuration...");
$self->log(LOG_INFO,"[SMRADIUS] Initializing configuration...");
smradius::config::Init($self);
$self->log(LOG_NOTICE,"[SMRADIUS] Configuration initialized.");
$self->log(LOG_INFO,"[SMRADIUS] Configuration initialized.");
# Load dictionaries
$self->log(LOG_NOTICE,"[SMRADIUS] Initializing dictionaries...");
my $dict = new Radius::Dictionary;
foreach my $fn (@{$config->{'dictionary'}->{'load'}}) {
$self->log(LOG_INFO,"[SMRADIUS] Initializing dictionaries...");
my $dict = smradius::Radius::Dictionary->new();
foreach my $df (@{$config->{'dictionary_list'}}) {
# Load dictionary
if (!$dict->readfile($fn)) {
$self->log(LOG_WARN,"[SMRADIUS] Failed to load dictionary '$fn': $!");
if (!$dict->readfile($df)) {
$self->log(LOG_WARN,"[SMRADIUS] Failed to load dictionary '$df': $!");
}
$self->log(LOG_DEBUG,"[SMRADIUS] Loaded plugin '$fn'.");
$self->log(LOG_DEBUG,"[SMRADIUS] Loaded dictionary '$df'.");
}
$self->log(LOG_NOTICE,"[SMRADIUS] Dictionaries initialized.");
$self->log(LOG_INFO,"[SMRADIUS] Dictionaries initialized.");
# Store the dictionary
$self->{'radius'}->{'dictionary'} = $dict;
$self->log(LOG_NOTICE,"[SMRADIUS] Initializing modules...");
# Load plugins
foreach my $plugin (@{$config->{'plugins'}}) {
# Load plugin
my $res = eval("
use $plugin;
plugin_register(\$self,\"$plugin\",\$${plugin}::pluginInfo);
");
$self->log(LOG_INFO,"[SMRADIUS] Initializing modules...");
# Load modules
foreach my $module (@{$config->{'module_list'}}) {
# Split off dir and mod name
$module =~ /^(\w+)\/(\w+)$/;
my ($mod_dir,$mod_name) = ($1,$2);
# Load module
## no critic (BuiltinFunctions::ProhibitStringyEval)
my $res = eval qq{
use smradius::modules::${mod_dir}::${mod_name};
plugin_register(\$self,\"${mod_name}\",\$smradius::modules::${mod_dir}::${mod_name}::pluginInfo);
};
## use critic
if ($@ || (defined($res) && $res != 0)) {
$self->log(LOG_WARN,"[SMRADIUS] Error loading plugin $plugin ($@)");
$self->log(LOG_WARN,"[SMRADIUS] Error loading module $module ($@)");
} else {
$self->log(LOG_DEBUG,"[SMRADIUS] Plugin '$plugin' loaded.");
$self->log(LOG_DEBUG,"[SMRADIUS] Plugin '$module' loaded.");
}
}
$self->log(LOG_NOTICE,"[SMRADIUS] Plugins initialized.");
$self->log(LOG_INFO,"[SMRADIUS] Plugins initialized.");
$self->log(LOG_NOTICE,"[SMRADIUS] Initializing system modules.");
$self->log(LOG_INFO,"[SMRADIUS] Initializing system modules.");
# Init caching engine
# smradius::cache::Init($self);
$self->log(LOG_NOTICE,"[SMRADIUS] System modules initialized.");
AWITPT::Cache::Init($self,{
'cache_file' => $self->{'config'}{'cache_file'},
'cache_file_user' => $self->{'server'}->{'user'},
'cache_file_group' => $self->{'server'}->{'group'}
});
$self->log(LOG_INFO,"[SMRADIUS] System modules initialized.");
return;
}
......@@ -337,30 +457,30 @@ sub plugin_register {
# Set real module name & save
$info->{'Module'} = $plugin;
push(@{$self->{'plugins'}},$info);
push(@{$self->{'module_list'}},$info);
# If we should, init the module
if (defined($info->{'Init'})) {
$info->{'Init'}($self);
}
return 0;
}
# Initialize child
sub child_init_hook
{
my $self = shift;
my $config = $self->{'config'};
$self->SUPER::child_init_hook();
$self->log(LOG_DEBUG,"[SMRADIUS] Starting up caching engine");
smradius::cache::connect($self);
$self->log(LOG_INFO,"[SMRADIUS] Starting up caching engine");
AWITPT::Cache::connect($self);
# Do we need database support?
if ($self->{'smradius'}->{'database'}->{'enabled'}) {
# This is the database connection timestamp, if we connect, it resets to 0
......@@ -368,20 +488,22 @@ sub child_init_hook
$self->{'client'}->{'dbh_status'} = time();
# Init core database support
$self->{'client'}->{'dbh'} = smradius::dbilayer::Init($self);
$self->{'client'}->{'dbh'} = AWITPT::DB::DBILayer::Init($self,'smradius');
if (defined($self->{'client'}->{'dbh'})) {
# Check if we succeeded
if (!($self->{'client'}->{'dbh'}->connect())) {
# If we succeeded, record OK
$self->{'client'}->{'dbh_status'} = 0;
} else {
$self->log(LOG_WARN,"[SMRADIUS] Failed to connect to database: ".$self->{'client'}->{'dbh'}->Error()." ($$)");
$self->log(LOG_WARN,"[SMRADIUS] Failed to connect to database: ".$self->{'client'}->{'dbh'}->error().
" ($$)");
}
} else {
$self->log(LOG_WARN,"[SMRADIUS] Failed to Initialize: ".smradius::dbilayer::internalErr()." ($$)");
$self->log(LOG_WARN,"[SMRADIUS] Failed to Initialize: ".AWITPT::DB::DBILayer::internalError()." ($$)");
}
}
return;
}
......@@ -392,32 +514,38 @@ sub child_finish_hook {
my $server = $self->{'server'};
$self->SUPER::child_finish_hook();
$self->log(LOG_DEBUG,"[SMRADIUS] Shutting down caching engine ($$)");
smradius::cache::disconnect($self);
$self->log(LOG_INFO,"[SMRADIUS] Shutting down caching engine ($$)");
AWITPT::Cache::disconnect($self);
return;
}
# Process requests we get
sub process_request {
my $self = shift;
my $server = $self->{'server'};
my $client = $self->{'client'};
my $log = defined($server->{'config'}{'logging'}{'modules'});
my $log = defined($server->{'config'}{'logging'}{'module_list'});
# Grab packet
my $udp_packet = $server->{'udp_data'};
my $rawPacket = $server->{'udp_data'};
# Check min size
if (length($udp_packet) < 18)
if (length($rawPacket) < 18)
{
$self->log(LOG_WARN, "[SMRADIUS] Packet too short - Ignoring");
return;
}
# Parse packet
my $pkt = new Radius::Packet($self->{'radius'}->{'dictionary'},$udp_packet);
# Very first timer ...
my $timer0 = [gettimeofday];
# Grab NOW()
my $now = time();
# VERIFY SOURCE SERVER
$self->log(LOG_DEBUG,"[SMRADIUS] Packet From = > ".$server->{'peeraddr'});
......@@ -429,14 +557,15 @@ sub process_request {
$self->log(LOG_WARN,"[SMRADIUS] Client in BYPASS mode due to DB connection failure!");
# Check bypass mode
if (!defined($self->{'inifile'}{'database'}{'bypass_mode'})) {
$self->log(LOG_ERR,"[SMRADIUS] No bypass_mode specified for failed database connections, defaulting to tempfail");
$self->log(LOG_ERR,
"[SMRADIUS] No bypass_mode specified for failed database connections, defaulting to tempfail");
$action = "tempfail";
# Check for "tempfail"
} elsif (lc($self->{'inifile'}{'database'}{'bypass_mode'}) eq "tempfail") {
# And for "bypass"
} elsif (lc($self->{'inifile'}{'database'}{'bypass_mode'}) eq "pass") {
}
# Check if we need to reconnect or not
my $timeout = $self->{'inifile'}{'database'}{'bypass_timeout'};
if (!defined($timeout)) {
......@@ -444,82 +573,104 @@ sub process_request {
$timeout = 120;
}
# Get time left
my $timepassed = time() - $self->{'client'}->{'dbh_status'};
my $timepassed = $now - $self->{'client'}->{'dbh_status'};
# Then check...
if ($timepassed >= $timeout) {
$self->log(LOG_NOTICE,"[SMRADIUS] Client BYPASS timeout exceeded, reconnecting...");
$self->log(LOG_WARN,"[SMRADIUS] Client BYPASS timeout exceeded, reconnecting...");
exit 0;
} else {
$self->log(LOG_NOTICE,"[SMRADIUS] Client still in BYPASS mode, ".( $timeout - $timepassed )."s left till next reconnect");
$self->log(LOG_WARN,"[SMRADIUS] Client still in BYPASS mode, ".( $timeout - $timepassed ).
"s left till next reconnect");
return;
}
}
# Setup database handle
smradius::dblayer::setHandle($self->{'client'}->{'dbh'});
#LOGIN
#Service-Type: Login-User
#User-Name: joe
#User-Password: \x{d3}\x{df}\x{10}\x{8c}\x{a0}r.\x{fd}=\x{ff}\x{96}\x{a}\x{86}\x{91}\x{e}c
#Calling-Station-Id: 10.254.254.242
#NAS-Identifier: lbsd-test
#NAS-IP-Address: 10.254.254.239
#PPPOE:
#Service-Type: Framed-User
#Framed-Protocol: PPP
#NAS-Port: 19
#NAS-Port-Type: Ethernet
#User-Name: nigel
#Calling-Station-Id: 00:E0:4D:2A:72:35
#Called-Station-Id: pppoe-24
#NAS-Port-Id: ether1
#NAS-Identifier: lbsd-test
#NAS-IP-Address: 10.254.254.239
#PPTP
#Service-Type: Framed-User
#Framed-Protocol: PPP
#NAS-Port: 49
#NAS-Port-Type: Virtual
#User-Name: johnsmith
#Calling-Station-Id: 10.254.254.242
#Called-Station-Id: 10.254.254.239
#NAS-Identifier: lbsd-test
#NAS-IP-Address: 10.254.254.239
# Main user hash with everything in
my $user;
$user->{'ConfigAttributes'} = {};
$user->{'ReplyAttributes'} = {};
$user->{'ReplyVAttributes'} = {};
# Private data
$user->{'_Internal'} = {
'Timestamp-Unix' => defined($pkt->rawattr('Event-Timestamp')) ? $pkt->rawattr('Event-Timestamp') : time()
};
my $eventTimestamp = DateTime->from_epoch( epoch => $user->{'_Internal'}->{'Timestamp-Unix'} );
$user->{'_Internal'}->{'Timestamp'} = $eventTimestamp->strftime('%Y-%m-%d %H:%M:%S');
AWITPT::DB::DBLayer::setHandle($self->{'client'}->{'dbh'});
my $request = smradius::daemon::request->new($self);
if (!$request->setTimezone($self->{'smradius'}->{'event_timezone'})) {
$self->log(LOG_ERR,"[SMRADIUS] Setting event_timezone to '%s' failed",$self->{'smradius'}->{'event_timezone'});
return;
}
$request->parsePacket($self->{'radius'}->{'dictionary'},$rawPacket);
# Check if we need to override the packet timestamp, if we are not using the packet timestamp, set it to when we go the packet
if (!booleanize($self->{'smradius'}->{'use_packet_timestamp'})) {
$request->setTimestamp($now);
}
# Username should always be defined?
if (!$request->hasUsername()) {
$self->log(LOG_NOTICE,"[SMRADIUS] Packet with no username from ".$server->{'peeraddr'});
return;
}
# TODO/FIXME: WIP
my $pkt = $request->{'packet'};
my $user = $request->{'user'};
my $logReason = "UNKNOWN";
# First thing we do is to make sure the NAS behaves if we using abuse prevention
if ($self->{'smradius'}->{'use_abuse_prevention'} && defined($user->{'Username'})) {
my ($res,$val) = cacheGetKeyPair('FloodCheck',$server->{'peeraddr'}."/".$user->{'Username'}."/".$pkt->code);
if (defined($val)) {
my $timePeriod = $now - $val;
# Check if we're still within the abuse threshold
if ($pkt->code eq "Access-Request" && $timePeriod < $self->{'smradius'}->{'access_request_abuse_threshold'}) {
$self->log(LOG_NOTICE,"[SMRADIUS] ABUSE: NAS trying too fast. NAS = ".$server->{'peeraddr'}.", user = ".$user->{'Username'}.
", code = ".$pkt->code.", timeout = ".($now - $val));
# Tell the NAS we got its packet
my $resp = smradius::Radius::Packet->new($self->{'radius'}->{'dictionary'});
$resp->set_code('Access-Reject');
$resp->set_identifier($pkt->identifier);
$resp->set_authenticator($pkt->authenticator);
$server->{'client'}->send(
auth_resp($resp->pack, getAttributeValue($user->{'ConfigAttributes'},"SMRadius-Config-Secret"))
);
return;
} elsif ($pkt->code eq "Accounting-Request" && $timePeriod < $self->{'smradius'}->{'accounting_request_abuse_threshold'}) {
$self->log(LOG_NOTICE,"[SMRADIUS] ABUSE: NAS trying too fast. NAS = ".$server->{'peeraddr'}.", user = ".$user->{'Username'}.
", code = ".$pkt->code.", timeout = ".($now - $val));
# Tell the NAS we got its packet
my $resp = smradius::Radius::Packet->new($self->{'radius'}->{'dictionary'});
$resp->set_code('Accounting-Response');
$resp->set_identifier($pkt->identifier);
$resp->set_authenticator($pkt->authenticator);
$server->{'client'}->send(
auth_resp($resp->pack, getAttributeValue($user->{'ConfigAttributes'},"SMRadius-Config-Secret"))
);
return;
}
}
# We give the benefit of the doubt and let a query take 60s. We update to right stamp at end of this function
cacheStoreKeyPair('FloodCheck',$server->{'peeraddr'}."/".$user->{'Username'}."/".$pkt->code,$now + 60);
}
#
# GRAB & PROCESS CONFIG
# GRAB & PROCESS CONFIG
#
foreach my $module (@{$self->{'plugins'}}) {
my $configured = 1;
foreach my $module (@{$self->{'module_list'}}) {
# Try find config attribute
if ($module->{'Config_get'}) {
# Get result from config module
$self->log(LOG_INFO,"[SMRADIUS] CONFIG: Trying plugin '".$module->{'Name'}."' for incoming connection");
$self->log(LOG_DEBUG,"[SMRADIUS] CONFIG: Trying plugin '".$module->{'Name'}."' for incoming connection");
my $res = $module->{'Config_get'}($self,$user,$pkt);
# Check result
if (!defined($res)) {
$self->log(LOG_DEBUG,"[SMRADIUS] CONFIG: Error with plugin '".$module->{'Name'}."'");
$self->log(LOG_WARN,"[SMRADIUS] CONFIG: Error with plugin '".$module->{'Name'}."'");
$logReason = "Config Error";
# Check if we skipping this plugin
} elsif ($res == MOD_RES_SKIP) {
......@@ -527,47 +678,79 @@ sub process_request {
# Check if we got a positive result back
} elsif ($res == MOD_RES_ACK) {
$self->log(LOG_NOTICE,"[SMRADIUS] CONFIG: Configuration retrieved from '".$module->{'Name'}."'");
$self->log(LOG_DEBUG,"[SMRADIUS] CONFIG: Configuration retrieved from '".$module->{'Name'}."'");
$logReason = "Config Retrieved";
# Check if we got a negative result back
} elsif ($res == MOD_RES_NACK) {
$self->log(LOG_NOTICE,"[SMRADIUS] CONFIG: Configuration problem when using '".$module->{'Name'}."'");
$self->log(LOG_DEBUG,"[SMRADIUS] CONFIG: Configuration rejection when using '".$module->{'Name'}."'");
$logReason = "Config Rejected";
# FIXME/TODO NK WIP
return;
# $configured = 0;
# last;
}
}
}
# FIXME - need secret
# FIXME - need acl list
#
# START PROCESSING
# USERNAME TRANSFORM
#
# UserDB module if we using/need it
my $userdb;
# If we have a config attribute to transform username, use it
if (defined($user->{'ConfigAttributes'}->{'SMRadius-Username-Transform'})) {
$self->log(LOG_DEBUG,"[SMRADIUS] Attribute 'SMRadius-Username-Transform' exists, transforming username.");
# NK: Not ready for prime time yet
# # Get clients(NAS) username transform pattern
# my $transform = shift(@{$user->{'ConfigAttributes'}->{'SMRadius-Username-Transform'}});
# if ($transform =~ /^(@\S+)=(@\S+)$/i) {
#
# # Set old and new, prevents warnings
# my ($old,$new) = ($1,$2);
#
# # Use client username transform on temp username
# my $tempUsername = $user->{'Username'};
# $tempUsername =~ s/$old/$new/;
#
# # Override username
# $user->{'Username'} = $tempUsername;
# } else {
# $self->log(LOG_DEBUG,"[SMRADIUS] No string replacement possible on pattern '".
# $transform."', using username '".$user->{'Username'}."'");
# }
}
#
# FIND USER
#
# Get the user timer
my $timer1 = [gettimeofday];
# FIXME - need secret
# FIXME - need acl list
# Common stuff for multiple codes....
if ($pkt->code eq "Accounting-Request" || $pkt->code eq "Access-Request") {
# Set username
$user->{'Username'} = $pkt->attr('User-Name');
$pkt->dump();
#
# FIND USER
#
# Loop with modules to try find user
foreach my $module (@{$self->{'plugins'}}) {
foreach my $module (@{$self->{'module_list'}}) {
# Try find user
if ($module->{'User_find'}) {
$self->log(LOG_INFO,"[SMRADIUS] FIND: Trying plugin '".$module->{'Name'}."' for username '".
$self->log(LOG_DEBUG,"[SMRADIUS] FIND: Trying plugin '".$module->{'Name'}."' for username '".
$user->{'Username'}."'");
my ($res,$userdb_data) = $module->{'User_find'}($self,$user,$pkt);
my ($res,$userDB_Data) = $module->{'User_find'}($self,$user,$pkt);
# Check result
if (!defined($res)) {
$self->log(LOG_DEBUG,"[SMRADIUS] FIND: Error with plugin '".$module->{'Name'}."'");
$self->log(LOG_WARN,"[SMRADIUS] FIND: Error with plugin '".$module->{'Name'}."'");
$logReason = "Error Finding User";
# Check if we skipping this plugin
} elsif ($res == MOD_RES_SKIP) {
......@@ -575,14 +758,17 @@ $pkt->dump();
# Check if we got a positive result back
} elsif ($res == MOD_RES_ACK) {
$self->log(LOG_NOTICE,"[SMRADIUS] FIND: Username found with '".$module->{'Name'}."'");
$userdb = $module;
$user->{'_UserDB_Data'} = $userdb_data;
$self->log(LOG_DEBUG,"[SMRADIUS] FIND: Username found with '".$module->{'Name'}."'");
$user->{'_UserDB'} = $module;
$user->{'_UserDB_Data'} = $userDB_Data;
# The user ID is supposed to be global unique, on the same level as the username
$user->{'ID'} = $user->{'_UserDB_Data'}->{'ID'};
last;
# Or a negative result
} elsif ($res == MOD_RES_NACK) {
$self->log(LOG_NOTICE,"[SMRADIUS] FIND: Username not found with '".$module->{'Name'}."'");
$self->log(LOG_DEBUG,"[SMRADIUS] FIND: Username not found with '".$module->{'Name'}."'");
$logReason = "User Not Found";
last;
}
......@@ -591,36 +777,55 @@ $pkt->dump();
}
#
# PROCESS PACKET
#
# Process the packet timer
my $timer2 = [gettimeofday];
# Is this an accounting request
if ($pkt->code eq "Accounting-Request") {
$self->log(LOG_DEBUG,"[SMRADIUS] Accounting Request Packet");
# Add onto logline
$request->addLogLine(". REQUEST => ");
foreach my $attrName ($pkt->attributes) {
$request->addLogLine(
"%s: '%s'",
$attrName,
$pkt->rawattr($attrName)
);
}
#
# GET USER
#
# Get user data
if (defined($userdb) && defined($userdb->{'User_get'})) {
my $res = $userdb->{'User_get'}($self,$user,$pkt);
if (defined($user->{'_UserDB'}) && defined($user->{'_UserDB'}->{'User_get'})) {
my $res = $user->{'_UserDB'}->{'User_get'}($self,$user,$pkt);
# Check result
if (defined($res) && ref($res) eq "HASH") {
# We're only after the attributes here
$user->{'Attributes'} = $res;
if ($res) {
$self->log(LOG_WARN,"[SMRADIUS] GET: Error returned from '".$user->{'_UserDB'}->{'Name'}.
"' for username '".$user->{'Username'}."'");
}
}
# Loop with modules to try something that handles accounting
foreach my $module (@{$self->{'plugins'}}) {
foreach my $module (@{$self->{'module_list'}}) {
# Try find user
if ($module->{'Accounting_log'}) {
$self->log(LOG_INFO,"[SMRADIUS] ACCT: Trying plugin '".$module->{'Name'}."'");
$self->log(LOG_DEBUG,"[SMRADIUS] ACCT: Trying plugin '".$module->{'Name'}."'");
my $res = $module->{'Accounting_log'}($self,$user,$pkt);
# Check result
if (!defined($res)) {
$self->log(LOG_DEBUG,"[SMRADIUS] ACCT: Error with plugin '".$module->{'Name'}."'");
$self->log(LOG_WARN,"[SMRADIUS] ACCT: Error with plugin '".$module->{'Name'}."'");
$logReason = "Accounting Log Error";
# Check if we skipping this plugin
} elsif ($res == MOD_RES_SKIP) {
......@@ -628,35 +833,32 @@ $pkt->dump();
# Check if we got a positive result back
} elsif ($res == MOD_RES_ACK) {
$self->log(LOG_NOTICE,"[SMRADIUS] ACCT: Accounting logged using '".$module->{'Name'}."'");
$self->log(LOG_DEBUG,"[SMRADIUS] ACCT: Accounting logged using '".$module->{'Name'}."'");
$logReason = "Accounting Logged";
# Check if we got a negative result back
} elsif ($res == MOD_RES_NACK) {
$self->log(LOG_NOTICE,"[SMRADIUS] ACCT: Accounting NOT LOGGED using '".$module->{'Name'}."'");
$self->log(LOG_DEBUG,"[SMRADIUS] ACCT: Accounting NOT LOGGED using '".$module->{'Name'}."'");
$logReason = "Accounting NOT Logged";
}
}
}
# Tell the NAS we got its packet
my $resp = Radius::Packet->new($self->{'radius'}->{'dictionary'});
$resp->set_code('Accounting-Response');
$resp->set_identifier($pkt->identifier);
$resp->set_authenticator($pkt->authenticator);
$udp_packet = auth_resp($resp->pack, getAttributeValue($user->{'ConfigAttributes'},"SMRadius-Config-Secret"));
$server->{'client'}->send($udp_packet);
my $killConnection = 0;
# Loop with features that have post-authentication hooks
foreach my $module (@{$self->{'plugins'}}) {
# Are we going to POD the user?
my $PODUser = 0;
# Loop with modules that have post-accounting hooks
foreach my $module (@{$self->{'module_list'}}) {
# Try authenticate
if ($module->{'Feature_Post-Accounting_hook'}) {
$self->log(LOG_INFO,"[SMRADIUS] POST-ACCT: Trying plugin '".$module->{'Name'}."' for '".
$self->log(LOG_DEBUG,"[SMRADIUS] POST-ACCT: Trying plugin '".$module->{'Name'}."' for '".
$user->{'Username'}."'");
my $res = $module->{'Feature_Post-Accounting_hook'}($self,$user,$pkt);
# Check result
if (!defined($res)) {
$self->log(LOG_DEBUG,"[SMRADIUS] POST-ACCT: Error with plugin '".$module->{'Name'}."'");
$self->log(LOG_WARN,"[SMRADIUS] POST-ACCT: Error with plugin '".$module->{'Name'}."'");
$logReason = "Post Accounting Error";
# Check if we skipping this plugin
} elsif ($res == MOD_RES_SKIP) {
......@@ -664,65 +866,190 @@ $pkt->dump();
# Check if we got a positive result back
} elsif ($res == MOD_RES_ACK) {
$self->log(LOG_NOTICE,"[SMRADIUS] POST-ACCT: Passed post accounting hook by '".$module->{'Name'}."'");
$self->log(LOG_DEBUG,"[SMRADIUS] POST-ACCT: Passed post accounting hook by '".$module->{'Name'}."'");
$logReason = "Post Accounting Success";
# Or a negative result
} elsif ($res == MOD_RES_NACK) {
$self->log(LOG_NOTICE,"[SMRADIUS] POST-ACCT: Failed post accounting hook by '".$module->{'Name'}."'");
#$authenticated = 0;
# Do we want to run the other features ??
#last;
$killConnection = 1;
$self->log(LOG_DEBUG,"[SMRADIUS] POST-ACCT: Failed post accounting hook by '".$module->{'Name'}."'");
$logReason = "Failed Post Accounting";
$PODUser = 1;
}
}
}
if ($killConnection == 1) {
# Tell the NAS we got its packet
my $resp = smradius::Radius::Packet->new($self->{'radius'}->{'dictionary'});
$resp->set_code('Accounting-Response');
$resp->set_identifier($pkt->identifier);
$resp->set_authenticator($pkt->authenticator);
$server->{'client'}->send(
auth_resp($resp->pack, getAttributeValue($user->{'ConfigAttributes'},"SMRadius-Config-Secret"))
);
$self->log(LOG_DEBUG,"[SMRADIUS] POST-ACCT: Trying to disconnect user...");
# CoA and POD only apply to accounting updates...
if ($pkt->rawattr('Acct-Status-Type') eq "3") {
my $resp = Radius::Packet->new($self->{'radius'}->{'dictionary'});
# Build a list of our attributes in the packet
my $acctAttributes;
foreach my $attr ($pkt->attributes) {
$acctAttributes->{$attr} = $pkt->rawattr($attr);
}
# Loop with attributes we got from the user
foreach my $attrName (keys %{$user->{'Attributes'}}) {
# Loop with operators
foreach my $attrOp (keys %{$user->{'Attributes'}->{$attrName}}) {
# Grab attribute
my $attr = $user->{'Attributes'}->{$attrName}->{$attrOp};
# Check attribute against accounting attributes
my $res = checkAcctAttribute($self,$user,$acctAttributes,$attr);
# We don't care if it fails
}
}
$resp->set_code('Disconnect-Request');
my $id = $$ & 0xff;
$resp->set_identifier( $id );
# The coaReq may be either POD or CoA
my $coaReq = smradius::Radius::Packet->new($self->{'radius'}->{'dictionary'});
$resp->set_attr('User-Name',$pkt->attr('User-Name'));
$resp->set_attr('Framed-IP-Address',$pkt->attr('Framed-IP-Address'));
$resp->set_attr('NAS-IP-Address',$pkt->attr('NAS-IP-Address'));
# Set packet identifier
$coaReq->set_identifier( $$ & 0xff );
$udp_packet = auth_resp($resp->pack, getAttributeValue($user->{'ConfigAttributes'},"SMRadius-Config-Secret"));
# Check if we must POD the user, if so we set the code to disconnect
if ($PODUser) {
$self->log(LOG_DEBUG,"[SMRADIUS] POST-ACCT: Trying to disconnect user...");
$coaReq->set_code('Disconnect-Request');
} else {
# If this is *not* a POD, we need to process reply attributes
$self->log(LOG_DEBUG,"[SMRADIUS] POST-ACCT: Sending CoA...");
$coaReq->set_code('CoA-Request');
# Process the reply attributes
$self->_processReplyAttributes($request,$user,$coaReq);
}
# Create socket to send packet out on
my $podServer = "10.254.254.239";
my $podServerPort = "1700";
my $podServerTimeout = "10"; # 10 second timeout
my $podSock = new IO::Socket::INET(
PeerAddr => $podServer,
PeerPort => $podServerPort,
Type => SOCK_DGRAM,
Proto => 'udp',
TimeOut => $podServerTimeout,
) or return $self->log(LOG_ERR,"[SMRADIUS] POST-ACCT: Failed to create socket to send POD on: $!");
$podSock->send ($udp_packet) || return $self->log(LOG_ERR,"[SMRADIUS] POST-ACCT: Failed to send data on socket: $!");
# NAS identification
$coaReq->set_attr('NAS-IP-Address',$pkt->attr('NAS-IP-Address'));
# Session identification
$coaReq->set_attr('User-Name',$pkt->attr('User-Name'));
$coaReq->set_attr('NAS-Port',$pkt->attr('NAS-Port'));
$coaReq->set_attr('Acct-Session-Id',$pkt->attr('Acct-Session-Id'));
# Add onto logline
$request->addLogLine(". REPLY => ");
foreach my $attrName ($coaReq->attributes) {
$request->addLogLine(
"%s: '%s'",
$attrName,
$coaReq->rawattr($attrName)
);
}
# Once sent, we need to get a response back
my $sh = new IO::Select($podSock) or return $self->log(LOG_ERR,"[SMRADIUS] POST-ACCT: Failed to select data on socket: $!");
$sh->can_read($podServerTimeout) or return $self->log(LOG_ERR,"[SMRADIUS] POST-ACCT: Failed to receive data on socket: $!");
# Generate coaReq packet
my $coaReq_packet = auth_resp($coaReq->pack, getAttributeValue($user->{'ConfigAttributes'},"SMRadius-Config-Secret"));
my $data;
$podSock->recv($data, 65536) or return $self->log(LOG_ERR,"[SMRADIUS] POST-ACCT: Receive data failed: $!");
# my @stuff = unpack('C C n a16 a*', $data);
# $self->log(LOG_DEBUG,"STUFF: ".Dumper(\@stuff));
}
# Array CoA servers to contact
my @coaServers;
# Check for old POD server attribute
if (defined($user->{'ConfigAttributes'}->{'SMRadius-Config-PODServer'})) {
$self->log(LOG_DEBUG,"[SMRADIUS] SMRadius-Config-PODServer is defined");
@coaServers = @{$user->{'ConfigAttributes'}->{'SMRadius-Config-PODServer'}};
}
# Check for new CoA server attribute
if (defined($user->{'ConfigAttributes'}->{'SMRadius-Config-CoAServer'})) {
$self->log(LOG_DEBUG,"[SMRADIUS] SMRadius-Config-CoAServer is defined");
@coaServers = @{$user->{'ConfigAttributes'}->{'SMRadius-Config-CoAServer'}};
}
# If we didn't get provided a CoA server, use the peer address
if (!@coaServers) {
push(@coaServers,$server->{'peeraddr'});
}
# Check address format
foreach my $coaServer (@coaServers) {
# Remove IPv6 portion for now...
$coaServer =~ s/^::ffff://;
# Check for valid IP
my ($coaServerIP,$coaServerPort) = ($coaServer =~ /^([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})(?::([0-9]+))?/);
if (!defined($coaServerIP)) {
$self->log(LOG_NOTICE,"[SMRADIUS] POST-ACCT: CoAServer '$coaServer' looks incorrect");
next;
}
# Set default CoA server port
$coaServerPort //= 1700;
$self->log(LOG_DEBUG,"[SMRADIUS] POST-ACCT: Trying CoAServer => IP: '".$coaServer."' Port: '".$coaServerPort."'");
# Create socket to send packet out on
my $coaServerTimeout = "2"; # 2 second timeout
my $coaSock = IO::Socket::INET->new(
PeerAddr => $coaServerIP,
PeerPort => $coaServerPort,
Type => SOCK_DGRAM,
Proto => 'udp',
TimeOut => $coaServerTimeout,
);
if (!$coaSock) {
$self->log(LOG_ERR,"[SMRADIUS] POST-ACCT: Failed to create socket to send CoA on: $!");
next;
}
# Check if we sent the packet...
if (!$coaSock->send($coaReq_packet)) {
$self->log(LOG_ERR,"[SMRADIUS] POST-ACCT: Failed to send data on CoA socket: $!");
next;
}
# Once sent, we need to get a response back
my $select = IO::Select->new($coaSock);
if (!$select) {
$self->log(LOG_ERR,"[SMRADIUS] POST-ACCT: Failed to select data on socket: $!");
next;
}
if (!$select->can_read($coaServerTimeout)) {
$self->log(LOG_ERR,"[SMRADIUS] POST-ACCT: Failed to receive data on socket: $!");
next;
}
# Grab CoA response
my $coaRes_packet;
$coaSock->recv($coaRes_packet, 65536);
if (!$coaRes_packet) {
$self->log(LOG_INFO,"[SMRADIUS] POST-ACCT: No data received in response to our request to '$coaServerIP:$coaServerPort': $!");
$request->addLogLine(". No response to CoA/POD");
next;
}
# Parse the radius packet
my $coaRes = smradius::Radius::Packet->new($self->{'radius'}->{'dictionary'},$coaRes_packet);
# Check status
if ($coaRes->code eq "CoA-ACK") {
$request->addLogLine(". CoA Success");
last;
} elsif ($coaRes->code eq "CoA-NACK") {
$request->addLogLine(". CoA Fail");
} elsif ($coaRes->code eq "Disconnect-ACK") {
$request->addLogLine(". POD Success");
last;
} elsif ($coaRes->code eq "Disconnect-NACK") {
$request->addLogLine(". POD Fail");
} else {
$request->addLogLine(". Invalid CoA/POD response");
}
}
}
# Or maybe a access request
} elsif ($pkt->code eq "Access-Request") {
$self->log(LOG_DEBUG,"[SMRADIUS] Access Request Packet");
# Authentication variables
my $authenticated = 0;
my $mechanism;
......@@ -731,8 +1058,8 @@ $pkt->dump();
# If no user is found, bork out ...
if (!defined($userdb)) {
$self->log(LOG_INFO,"[SMRADIUS] FIND: No plugin found for username '".$user->{'Username'}."'");
if (!defined($user->{'_UserDB'})) {
$self->log(LOG_DEBUG,"[SMRADIUS] FIND: No plugin found for username '".$user->{'Username'}."'");
goto CHECK_RESULT;
}
......@@ -741,18 +1068,17 @@ $pkt->dump();
#
# Get user data
if ($userdb->{'User_get'}) {
my $res = $userdb->{'User_get'}($self,$user,$pkt);
if ($user->{'_UserDB'}->{'User_get'}) {
my $res = $user->{'_UserDB'}->{'User_get'}($self,$user,$pkt);
# Check result
if (!defined($res) || ref($res) ne "HASH") {
$self->log(LOG_WARN,"[SMRADIUS] GET: No data returned from '".$userdb->{'Name'}."' for username '".$user->{'Username'}."'");
if ($res) {
$self->log(LOG_WARN,"[SMRADIUS] GET: Error returned from '".$user->{'_UserDB'}->{'Name'}.
"' for username '".$user->{'Username'}."'");
goto CHECK_RESULT;
}
# Setup user dataw
$user->{'Attributes'} = $res;
} else {
$self->log(LOG_INFO,"[SMRADIUS] GET: No 'User_get' function available for module '".$userdb->{'Name'}."'");
$self->log(LOG_ERR,"[SMRADIUS] GET: No 'User_get' function available for module '".$user->{'_UserDB'}->{'Name'}."'");
goto CHECK_RESULT;
}
......@@ -762,15 +1088,15 @@ $pkt->dump();
#
# Loop with authentication modules
foreach my $module (@{$self->{'plugins'}}) {
foreach my $module (@{$self->{'module_list'}}) {
# Try authenticate
if ($module->{'Authentication_try'}) {
$self->log(LOG_INFO,"[SMRADIUS] AUTH: Trying plugin '".$module->{'Name'}."' for '".$user->{'Username'}."'");
$self->log(LOG_DEBUG,"[SMRADIUS] AUTH: Trying plugin '".$module->{'Name'}."' for '".$user->{'Username'}."'");
my $res = $module->{'Authentication_try'}($self,$user,$pkt);
# Check result
if (!defined($res)) {
$self->log(LOG_DEBUG,"[SMRADIUS] AUTH: Error with plugin '".$module->{'Name'}."'");
$self->log(LOG_ERR,"[SMRADIUS] AUTH: Error with plugin '".$module->{'Name'}."'");
# Check if we skipping this plugin
} elsif ($res == MOD_RES_SKIP) {
......@@ -778,14 +1104,16 @@ $pkt->dump();
# Check if we got a positive result back
} elsif ($res == MOD_RES_ACK) {
$self->log(LOG_NOTICE,"[SMRADIUS] AUTH: Authenticated by '".$module->{'Name'}."'");
$self->log(LOG_DEBUG,"[SMRADIUS] AUTH: Authenticated by '".$module->{'Name'}."'");
$logReason = "User Authenticated";
$mechanism = $module;
$authenticated = 1;
last;
# Or a negative result
} elsif ($res == MOD_RES_NACK) {
$self->log(LOG_NOTICE,"[SMRADIUS] AUTH: Failed authentication by '".$module->{'Name'}."'");
$self->log(LOG_DEBUG,"[SMRADIUS] AUTH: Failed authentication by '".$module->{'Name'}."'");
$logReason = "User NOT Authenticated";
$mechanism = $module;
last;
......@@ -793,17 +1121,19 @@ $pkt->dump();
}
}
# Loop with features that have post-authentication hooks
# Loop with modules that have post-authentication hooks
if ($authenticated) {
foreach my $module (@{$self->{'plugins'}}) {
foreach my $module (@{$self->{'module_list'}}) {
# Try authenticate
if ($module->{'Feature_Post-Authentication_hook'}) {
$self->log(LOG_INFO,"[SMRADIUS] POST-AUTH: Trying plugin '".$module->{'Name'}."' for '".$user->{'Username'}."'");
$self->log(LOG_DEBUG,"[SMRADIUS] POST-AUTH: Trying plugin '".$module->{'Name'}.
"' for '".$user->{'Username'}."'");
my $res = $module->{'Feature_Post-Authentication_hook'}($self,$user,$pkt);
# Check result
if (!defined($res)) {
$self->log(LOG_DEBUG,"[SMRADIUS] POST-AUTH: Error with plugin '".$module->{'Name'}."'");
$self->log(LOG_ERR,"[SMRADIUS] POST-AUTH: Error with plugin '".$module->{'Name'}."'");
# Check if we skipping this plugin
} elsif ($res == MOD_RES_SKIP) {
......@@ -811,13 +1141,15 @@ $pkt->dump();
# Check if we got a positive result back
} elsif ($res == MOD_RES_ACK) {
$self->log(LOG_NOTICE,"[SMRADIUS] POST-AUTH: Passed authenticated by '".$module->{'Name'}."'");
$self->log(LOG_DEBUG,"[SMRADIUS] POST-AUTH: Passed authenticated by '".$module->{'Name'}."'");
$logReason = "Post Authentication Success";
# Or a negative result
} elsif ($res == MOD_RES_NACK) {
$self->log(LOG_NOTICE,"[SMRADIUS] POST-AUTH: Failed authentication by '".$module->{'Name'}."'");
$self->log(LOG_DEBUG,"[SMRADIUS] POST-AUTH: Failed authentication by '".$module->{'Name'}."'");
$logReason = "Post Authentication Failure";
$authenticated = 0;
# Do we want to run the other features ??
# Do we want to run the other modules ??
last;
}
}
......@@ -833,6 +1165,8 @@ $pkt->dump();
foreach my $attr ($pkt->attributes) {
$authAttributes->{$attr} = $pkt->rawattr($attr);
}
# Peer address
$authAttributes->{'SMRadius-Peer-Address'} = $server->{'peeraddr'};
# Loop with attributes we got from the user
foreach my $attrName (keys %{$user->{'Attributes'}}) {
# Loop with operators
......@@ -840,7 +1174,7 @@ $pkt->dump();
# Grab attribute
my $attr = $user->{'Attributes'}->{$attrName}->{$attrOp};
# Check attribute against authorization attributes
my $res = checkAuthAttribute($self,$authAttributes,$attr);
my $res = checkAuthAttribute($self,$user,$authAttributes,$attr);
if ($res == 0) {
$authorized = 0;
last;
......@@ -853,46 +1187,19 @@ $pkt->dump();
# Check if we authenticated or not
if ($authenticated && $authorized) {
$self->log(LOG_DEBUG,"[SMRADIUS] Authenticated and authorized");
$logReason = "User Authorized";
my $resp = Radius::Packet->new($self->{'radius'}->{'dictionary'});
$resp->set_code('Access-Accept');
my $resp = smradius::Radius::Packet->new($self->{'radius'}->{'dictionary'});
$resp->set_code('Access-Accept');
$resp->set_identifier($pkt->identifier);
$resp->set_authenticator($pkt->authenticator);
# Loop with attributes we got from the getReplyAttributes function, its a hash of arrays which are the values
my %replyAttributes = %{ $user->{'ReplyAttributes'} };
foreach my $attrName (keys %{$user->{'Attributes'}}) {
# Loop with operators
foreach my $attrOp (keys %{$user->{'Attributes'}->{$attrName}}) {
# Grab attribute
my $attr = $user->{'Attributes'}->{$attrName}->{$attrOp};
# Add this to the reply attribute?
setReplyAttribute($self,\%replyAttributes,$attr);
}
}
# Loop with reply attributes
foreach my $attrName (keys %replyAttributes) {
# Loop with values
foreach my $value (@{$replyAttributes{$attrName}}) {
# Add each value
$resp->set_attr($attrName,$value);
}
}
# Loop with vendor reply attributes
my %replyVAttributes = %{ $user->{'ReplyVAttributes'} };
foreach my $vendor (keys %replyVAttributes) {
# Loop with operators
foreach my $attrName (keys %{$replyVAttributes{$vendor}}) {
# Add each value
foreach my $value (@{$replyVAttributes{$vendor}->{$attrName}}) {
$resp->set_vsattr($vendor,$attrName,$value);
}
}
}
# Process the reply attributes
$self->_processReplyAttributes($request,$user,$resp);
$udp_packet = auth_resp($resp->pack, getAttributeValue($user->{'ConfigAttributes'},"SMRadius-Config-Secret"));
$server->{'client'}->send($udp_packet);
$server->{'client'}->send(
auth_resp($resp->pack, getAttributeValue($user->{'ConfigAttributes'},"SMRadius-Config-Secret"))
);
}
......@@ -900,13 +1207,15 @@ CHECK_RESULT:
# Check if found and authenticated
if (!$authenticated || !$authorized) {
$self->log(LOG_DEBUG,"[SMRADIUS] Authentication or authorization failure");
$logReason = "User NOT Authenticated or Authorized";
my $resp = Radius::Packet->new($self->{'radius'}->{'dictionary'});
$resp->set_code('Access-Reject');
my $resp = smradius::Radius::Packet->new($self->{'radius'}->{'dictionary'});
$resp->set_code('Access-Reject');
$resp->set_identifier($pkt->identifier);
$resp->set_authenticator($pkt->authenticator);
$udp_packet = auth_resp($resp->pack, getAttributeValue($user->{'ConfigAttributes'},"SMRadius-Config-Secret"));
$server->{'client'}->send($udp_packet);
$server->{'client'}->send(
auth_resp($resp->pack, getAttributeValue($user->{'ConfigAttributes'},"SMRadius-Config-Secret"))
);
}
# We don't know how to handle this
......@@ -914,32 +1223,61 @@ CHECK_RESULT:
$self->log(LOG_WARN,"[SMRADIUS] We cannot handle code: '".$pkt->code."'");
}
# END
my $timer9 = [gettimeofday];
my $timediff1 = tv_interval($timer0,$timer1);
my $timediff2 = tv_interval($timer1,$timer2);
my $timediff3 = tv_interval($timer2,$timer9);
my $timediff = tv_interval($timer0,$timer9);
# FIXME/TODO NK WIP
my $logLine = join(' ',@{$request->{'logLine'}});
my @logLineArgs = @{$request->{'logLineParams'}};
# How should we output this ...
if ($server->{'log_level'} > LOG_NOTICE) {
$self->log(LOG_NOTICE,"[SMRADIUS] Result: $logReason (%.3fs + %.3fs + %.3fs = %.3fs) => $logLine",
$timediff1,$timediff2,$timediff3,$timediff,@logLineArgs);
} else {
$self->log(LOG_NOTICE,"[SMRADIUS] Result: $logReason => $logLine",@logLineArgs);
}
# If we using abuse prevention record the time we ending off
if ($self->{'smradius'}->{'use_abuse_prevention'} && defined($user->{'Username'})) {
cacheStoreKeyPair('FloodCheck',$server->{'peeraddr'}."/".$user->{'Username'}."/".$pkt->code,time());
}
return;
}
# Initialize child
sub server_exit
{
my $self = shift;
$self->log(LOG_DEBUG,"Destroying system modules.");
# Destroy cache
# cbp::cache::Destroy($self);
AWITPT::Cache::Destroy($self);
$self->log(LOG_DEBUG,"System modules destroyed.");
# Parent exit
$self->SUPER::server_exit();
return;
}
# Slightly better logging
sub log
sub log ## no critic (Subroutines::ProhibitBuiltinHomonyms)
{
my ($self,$level,$msg,@args) = @_;
# Check log level and set text
my $logtxt = "UNKNOWN";
if ($level == LOG_DEBUG) {
......@@ -952,7 +1290,7 @@ sub log
$logtxt = "WARNING";
} elsif ($level == LOG_ERR) {
$logtxt = "ERROR";
}
}
# Parse message nicely
if ($msg =~ /^(\[[^\]]+\]) (.*)/s) {
......@@ -961,14 +1299,19 @@ sub log
$msg = "[CORE] $logtxt: $msg";
}
$self->SUPER::log($level,"[".$self->log_time." - $$] $msg",@args);
# If we have args, this is more than likely a format string & args
if (@args > 0) {
$msg = sprintf($msg,@args);
}
return $self->SUPER::log($level,"[".$self->log_time." - $$] $msg");
}
# Display help
sub displayHelp {
print(STDERR "SMRadius v".VERSION." - Copyright (c) 2007-2009, AllWorldIT\n");
print(STDERR "SMRadius v$VERSION - Copyright (c) 2007-2016, AllWorldIT\n");
print(STDERR<<EOF);
......@@ -978,13 +1321,133 @@ Usage: $0 [args]
--fg Don't go into background
EOF
return;
}
#
# Internal functions
#
# Process reply attributes
sub _processReplyAttributes
{
my ($self,$request,$user,$pkt) = @_;
# Add attributes we got from plugins and process attributes attached to the user
my %replyAttributes = %{ $user->{'ReplyAttributes'} };
foreach my $attrName (keys %{$user->{'Attributes'}}) {
# Loop with operators
foreach my $attrOp (keys %{$user->{'Attributes'}->{$attrName}}) {
# Grab attribute
my $attr = $user->{'Attributes'}->{$attrName}->{$attrOp};
# Add this to the reply attribute?
setReplyAttribute($self,\%replyAttributes,$attr);
}
}
# Add vendor attributes we got from plugins and process attributes attached to the user
my %replyVAttributes = %{ $user->{'ReplyVAttributes'} };
foreach my $attrName (keys %{$user->{'VAttributes'}}) {
# Loop with operators
foreach my $attrOp (keys %{$user->{'VAttributes'}->{$attrName}}) {
# Grab attribute
my $attr = $user->{'VAttributes'}->{$attrName}->{$attrOp};
# Add this to the reply attribute?
setReplyVAttribute($self,\%replyVAttributes,$attr);
}
}
# Loop with reply attributes add them to our response, or output them to log if they were excluded
$request->addLogLine("RFILTER => ");
foreach my $attrName (keys %replyAttributes) {
# Loop with values
foreach my $value (@{$replyAttributes{$attrName}}) {
# Check for filter matches
my $excluded = 0;
foreach my $item (@{$user->{'ConfigAttributes'}->{'SMRadius-Config-Filter-Reply-Attribute'}}) {
my @attrList = split(/[;,]/,$item);
foreach my $aItem (@attrList) {
$excluded = 1 if (lc($attrName) eq lc($aItem));
}
}
# If we must be filtered, just exclude it then
if (!$excluded) {
# Add each value
$pkt->set_attr($attrName,$value);
} else {
$request->addLogLine("%s ",$attrName);
}
}
}
# Loop with reply vendor attributes add them to our response, or output them to log if they were excluded
$request->addLogLine(". RVFILTER => ");
# Process reply vattributes already added
foreach my $vendor (keys %replyVAttributes) {
# Loop with operators
foreach my $attrName (keys %{$replyVAttributes{$vendor}}) {
# Add each value
foreach my $value (@{$replyVAttributes{$vendor}->{$attrName}}) {
# Check for filter matches
my $excluded = 0;
foreach my $item (@{$user->{'ConfigAttributes'}->{'SMRadius-Config-Filter-Reply-VAttribute'}}) {
my @attrList = split(/[;,]/,$item);
foreach my $aItem (@attrList) {
$excluded = 1 if (lc($attrName) eq lc($aItem));
}
}
# If we must be filtered, just exclude it then
if (!$excluded) {
# This attribute is not excluded, so its ok
$pkt->set_vsattr($vendor,$attrName,$value);
} else {
$request->addLogLine("%s ",$attrName);
}
}
}
}
# Add attributes onto logline
$request->addLogLine(". REPLY => ");
foreach my $attrName ($pkt->attributes) {
$request->addLogLine(
"%s: '%s",
$attrName,
$pkt->rawattr($attrName)
);
}
# Add vattributes onto logline
$request->addLogLine(". VREPLY => ");
# Loop with vendors
foreach my $vendor ($pkt->vendors()) {
# Loop with attributes
foreach my $attrName ($pkt->vsattributes($vendor)) {
# Grab the value
my @attrRawVal = ( $pkt->vsattr($vendor,$attrName) );
my $attrVal = $attrRawVal[0][0];
# Sanatize it a bit
if ($attrVal =~ /[[:cntrl:]]/) {
$attrVal = "-nonprint-";
} else {
$attrVal = "'$attrVal'";
}
$request->addLogLine(
"%s/%s: %s",
$vendor,
$attrName,
$attrVal
);
}
}
return $self;
};
__PACKAGE__->run;
1;
# vim: ts=4
# Radius daemon request processing
# Copyright (C) 2007-2016, AllWorldIT
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
package smradius::daemon::request;
use strict;
use warnings;
use base qw{AWITPT::Object};
use DateTime;
use DateTime::TimeZone;
use Try::Tiny;
use smradius::Radius::Packet;
# Parse radius packet
sub parsePacket
{
my ($self,$dictionary,$rawPacket) = @_;
# Parse the radius packet
$self->{'packet'} = smradius::Radius::Packet->new($dictionary,$rawPacket);
# Loop with packet attribute names and add to our log line
$self->addLogLine("PACKET => ");
foreach my $attrName (sort $self->{'packet'}->attributes()) {
# Make the value a bit more pretty to print
my $attrVal;
if ($attrName eq "User-Password") {
$attrVal = "-encrypted-";
} else {
$attrVal = $self->{'packet'}->rawattr($attrName);
}
# Add it onto the log line...
$self->addLogLine(
"%s: '%s'",
$attrName,
$attrVal,
);
}
# Set the username
$self->{'user'}->{'Username'} = $self->{'packet'}->attr('User-Name');
# Set the packet timestamp in unix time
if (my $timestamp = $self->{'packet'}->rawattr('Event-Timestamp')) {
$self->setTimestamp($timestamp);
} else {
$self->setTimestamp(time());
}
return $self;
}
# Set internal timestamp
sub setTimestamp
{
my ($self,$timestamp) = @_;
# Set timestamp
$self->{'user'}->{'_Internal'}->{'Timestamp-Unix'} = $timestamp;
# Grab real event timestamp in local time uzing the time zone
my $eventTimestamp = DateTime->from_epoch(
epoch => $self->{'user'}->{'_Internal'}->{'Timestamp-Unix'},
time_zone => $self->{'timezone'},
);
# Set the timestamp (not in unix)
$self->{'user'}->{'_Internal'}->{'Timestamp'} = $eventTimestamp->strftime('%Y-%m-%d %H:%M:%S');
return $self;
}
# Set internal time zone
sub setTimezone
{
my ($self,$timezone) = @_;
my $timezone_obj;
try {
$timezone_obj = DateTime::TimeZone->new('name' => $timezone);
};
# Retrun if we don't have a value, this means we failed
return if (!defined($timezone_obj));
$self->{'timezone'} = $timezone_obj;
return $self;
}
# Add something onto the log line in printf() style...
sub addLogLine
{
my ($self,$template,@params) = @_;
# Add on template and params
push(@{$self->{'logLine'}},$template);
push(@{$self->{'logLineParams'}},@params);
return $self;
}
# Return if the Username attribute of the user is defined
sub hasUsername
{
my $self = shift;
return defined($self->{'user'}->{'Username'});
}
#
# INTERNAL METHODS
#
# This method is called from the new-> method during instantiation
sub _init
{
my ($self) = @_;
# Initialize log line
$self->{'logLine'} = [ ];
$self->{'logLineParams'} = [ ];
$self->{'timezone'} = "UTC";
# Initialize user
$self->{'user'} = {
'Username' => undef,
'ConfigAttributes' => { },
'Attributes' => { },
'VAttributes' => { },
'ReplyAttributes' => { },
'ReplyVAttributes' => { },
'AttributeConditionalVariables' => { },
};
return $self;
}
1;
# vim: ts=4
# Logging constants
# Copyright (C) 2007-2009, AllWorldIT
# Copyright (C) 2007-2015, AllWorldIT
#
# 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
......
# SQL accounting database
# Copyright (C) 2007-2019, AllWorldIT
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
package smradius::modules::accounting::mod_accounting_sql;
use strict;
use warnings;
# Modules we need
use smradius::constants;
use AWITPT::Cache;
use AWITPT::DB::DBLayer;
use AWITPT::Util;
use smradius::logging;
use smradius::util;
use POSIX qw(ceil);
use DateTime;
use Math::BigInt;
use Math::BigFloat;
# Exporter stuff
use base qw(Exporter);
our @EXPORT = qw(
);
our @EXPORT_OK = qw(
);
# Plugin info
our $pluginInfo = {
Name => "SQL Accounting Database",
Init => \&init,
# Cleanup run by smadmin
CleanupOrder => 30,
Cleanup => \&cleanup,
# Accounting database
Accounting_log => \&acct_log,
Accounting_getUsage => \&getUsage
};
# Module config
my $config;
## @internal
# Initialize module
sub init
{
my $server = shift;
my $scfg = $server->{'inifile'};
# Enable support for database
$server->log(LOG_NOTICE,"[MOD_ACCOUNTING_SQL] Enabling database support");
if (!$server->{'smradius'}->{'database'}->{'enabled'}) {
$server->log(LOG_NOTICE,"[MOD_ACCOUNTING_SQL] Enabling database support.");
$server->{'smradius'}->{'database'}->{'enabled'} = 1;
}
# Default configs...
$config->{'accounting_start_query'} = '
INSERT INTO
@TP@accounting
(
Username,
ServiceType,
FramedProtocol,
NASPort,
NASPortType,
CallingStationID,
CalledStationID,
NASPortID,
AcctSessionID,
FramedIPAddress,
AcctAuthentic,
EventTimestamp,
AcctStatusType,
NASIdentifier,
NASIPAddress,
AcctDelayTime,
AcctSessionTime,
AcctInputOctets,
AcctInputGigawords,
AcctInputPackets,
AcctOutputOctets,
AcctOutputGigawords,
AcctOutputPackets,
PeriodKey
)
VALUES
(
%{user.Username},
%{request.Service-Type},
%{request.Framed-Protocol},
%{request.NAS-Port},
%{request.NAS-Port-Type},
%{request.Calling-Station-Id},
%{request.Called-Station-Id},
%{request.NAS-Port-Id},
%{request.Acct-Session-Id},
%{request.Framed-IP-Address},
%{request.Acct-Authentic},
%{request.Timestamp},
%{request.Acct-Status-Type},
%{request.NAS-Identifier},
%{request.NAS-IP-Address},
%{request.Acct-Delay-Time},
%{request.Acct-Session-Time},
%{request.Acct-Input-Octets},
%{request.Acct-Input-Gigawords},
%{request.Acct-Input-Packets},
%{request.Acct-Output-Octets},
%{request.Acct-Output-Gigawords},
%{request.Acct-Output-Packets},
%{query.PeriodKey}
)
';
$config->{'accounting_update_get_records_query'} = '
SELECT
SUM(AcctInputOctets) AS AcctInputOctets,
SUM(AcctInputPackets) AS AcctInputPackets,
SUM(AcctOutputOctets) AS AcctOutputOctets,
SUM(AcctOutputPackets) AS AcctOutputPackets,
SUM(AcctInputGigawords) AS AcctInputGigawords,
SUM(AcctOutputGigawords) AS AcctOutputGigawords,
SUM(AcctSessionTime) AS AcctSessionTime,
PeriodKey
FROM
@TP@accounting
WHERE
Username = %{user.Username}
AND AcctSessionID = %{request.Acct-Session-Id}
AND NASIPAddress = %{request.NAS-IP-Address}
AND NASPort = %{request.NAS-Port}
GROUP BY
PeriodKey
ORDER BY
ID ASC
';
$config->{'accounting_update_query'} = '
UPDATE
@TP@accounting
SET
AcctSessionTime = %{query.Acct-Session-Time},
AcctInputOctets = %{query.Acct-Input-Octets},
AcctInputGigawords = %{query.Acct-Input-Gigawords},
AcctInputPackets = %{query.Acct-Input-Packets},
AcctOutputOctets = %{query.Acct-Output-Octets},
AcctOutputGigawords = %{query.Acct-Output-Gigawords},
AcctOutputPackets = %{query.Acct-Output-Packets},
AcctStatusType = %{request.Acct-Status-Type}
WHERE
Username = %{user.Username}
AND AcctSessionID = %{request.Acct-Session-Id}
AND NASIPAddress = %{request.NAS-IP-Address}
AND NASPort = %{request.NAS-Port}
AND PeriodKey = %{query.PeriodKey}
';
$config->{'accounting_stop_status_query'} = '
UPDATE
@TP@accounting
SET
AcctStatusType = %{request.Acct-Status-Type},
AcctTerminateCause = %{request.Acct-Terminate-Cause}
WHERE
Username = %{user.Username}
AND AcctSessionID = %{request.Acct-Session-Id}
AND NASIPAddress = %{request.NAS-IP-Address}
AND NASPort = %{request.NAS-Port}
';
$config->{'accounting_usage_query'} = '
SELECT
SUM(AcctInputOctets) AS AcctInputOctets,
SUM(AcctOutputOctets) AS AcctOutputOctets,
SUM(AcctInputGigawords) AS AcctInputGigawords,
SUM(AcctOutputGigawords) AS AcctOutputGigawords,
SUM(AcctSessionTime) AS AcctSessionTime
FROM
@TP@accounting
WHERE
Username = %{user.Username}
AND PeriodKey = %{query.PeriodKey}
';
$config->{'accounting_usage_query_period'} = '
SELECT
SUM(AcctInputOctets) AS AcctInputOctets,
SUM(AcctOutputOctets) AS AcctOutputOctets,
SUM(AcctInputGigawords) AS AcctInputGigawords,
SUM(AcctOutputGigawords) AS AcctOutputGigawords,
SUM(AcctSessionTime) AS AcctSessionTime
FROM
@TP@accounting
WHERE
Username = %{user.Username}
AND EventTimestamp > %{query.PeriodKey}
';
$config->{'accounting_select_duplicates_query'} = '
SELECT
ID
FROM
@TP@accounting
WHERE
Username = %{user.Username}
AND AcctSessionID = %{request.Acct-Session-Id}
AND NASIPAddress = %{request.NAS-IP-Address}
AND NASPort = %{request.NAS-Port}
AND PeriodKey = %{query.PeriodKey}
ORDER BY
ID
LIMIT 99 OFFSET 1
';
$config->{'accounting_delete_duplicates_query'} = '
DELETE FROM
@TP@accounting
WHERE
ID = %{query.DuplicateID}
';
$config->{'accounting_usage_cache_time'} = 300;
# Setup SQL queries
if (defined($scfg->{'mod_accounting_sql'})) {
# Pull in queries
if (defined($scfg->{'mod_accounting_sql'}->{'accounting_start_query'}) &&
$scfg->{'mod_accounting_sql'}->{'accounting_start_query'} ne "") {
if (ref($scfg->{'mod_accounting_sql'}->{'accounting_start_query'}) eq "ARRAY") {
$config->{'accounting_start_query'} = join(' ',
@{$scfg->{'mod_accounting_sql'}->{'accounting_start_query'}});
} else {
$config->{'accounting_start_query'} = $scfg->{'mod_accounting_sql'}->{'accounting_start_query'};
}
}
if (defined($scfg->{'mod_accounting_sql'}->{'accounting_update_get_records_query'}) &&
$scfg->{'mod_accounting_sql'}->{'accounting_update_get_records_query'} ne "") {
if (ref($scfg->{'mod_accounting_sql'}->{'accounting_update_get_records_query'}) eq "ARRAY") {
$config->{'accounting_update_get_records_query'} = join(' ',
@{$scfg->{'mod_accounting_sql'}->{'accounting_update_get_records_query'}});
} else {
$config->{'accounting_update_get_records_query'} = $scfg->{'mod_accounting_sql'}->{'accounting_update_get_records_query'};
}
}
if (defined($scfg->{'mod_accounting_sql'}->{'accounting_update_query'}) &&
$scfg->{'mod_accounting_sql'}->{'accounting_update_query'} ne "") {
if (ref($scfg->{'mod_accounting_sql'}->{'accounting_update_query'}) eq "ARRAY") {
$config->{'accounting_update_query'} = join(' ',
@{$scfg->{'mod_accounting_sql'}->{'accounting_update_query'}});
} else {
$config->{'accounting_update_query'} = $scfg->{'mod_accounting_sql'}->{'accounting_update_query'};
}
}
if (defined($scfg->{'mod_accounting_sql'}->{'accounting_stop_status_query'}) &&
$scfg->{'mod_accounting_sql'}->{'accounting_stop_status_query'} ne "") {
if (ref($scfg->{'mod_accounting_sql'}->{'accounting_stop_status_query'}) eq "ARRAY") {
$config->{'accounting_stop_status_query'} = join(' ',
@{$scfg->{'mod_accounting_sql'}->{'accounting_stop_status_query'}});
} else {
$config->{'accounting_stop_status_query'} = $scfg->{'mod_accounting_sql'}->{'accounting_stop_status_query'};
}
}
if (defined($scfg->{'mod_accounting_sql'}->{'accounting_usage_query'}) &&
$scfg->{'mod_accounting_sql'}->{'accounting_usage_query'} ne "") {
if (ref($scfg->{'mod_accounting_sql'}->{'accounting_usage_query'}) eq "ARRAY") {
$config->{'accounting_usage_query'} = join(' ',
@{$scfg->{'mod_accounting_sql'}->{'accounting_usage_query'}});
} else {
$config->{'accounting_usage_query'} = $scfg->{'mod_accounting_sql'}->{'accounting_usage_query'};
}
}
if (defined($scfg->{'mod_accounting_sql'}->{'accounting_usage_query_period'}) &&
$scfg->{'mod_accounting_sql'}->{'accounting_usage_query_period'} ne "") {
if (ref($scfg->{'mod_accounting_sql'}->{'accounting_usage_query_period'}) eq "ARRAY") {
$config->{'accounting_usage_query_period'} = join(' ',
@{$scfg->{'mod_accounting_sql'}->{'accounting_usage_query_period'}});
} else {
$config->{'accounting_usage_query_period'} = $scfg->{'mod_accounting_sql'}->{'accounting_usage_query_period'};
}
}
if (defined($scfg->{'mod_accounting_sql'}->{'accounting_select_duplicates_query'}) &&
$scfg->{'mod_accounting_sql'}->{'accounting_select_duplicates_query'} ne "") {
if (ref($scfg->{'mod_accounting_sql'}->{'accounting_select_duplicates_query'}) eq "ARRAY") {
$config->{'accounting_select_duplicates_query'} = join(' ',
@{$scfg->{'mod_accounting_sql'}->{'accounting_select_duplicates_query'}});
} else {
$config->{'accounting_select_duplicates_query'} = $scfg->{'mod_accounting_sql'}->{'accounting_select_duplicates_query'};
}
}
if (defined($scfg->{'mod_accounting_sql'}->{'accounting_delete_duplicates_query'}) &&
$scfg->{'mod_accounting_sql'}->{'accounting_delete_duplicates_query'} ne "") {
if (ref($scfg->{'mod_accounting_sql'}->{'accounting_delete_duplicates_query'}) eq "ARRAY") {
$config->{'accounting_delete_duplicates_query'} = join(' ',
@{$scfg->{'mod_accounting_sql'}->{'accounting_delete_duplicates_query'}});
} else {
$config->{'accounting_delete_duplicates_query'} = $scfg->{'mod_accounting_sql'}->{'accounting_delete_duplicates_query'};
}
}
if (defined($scfg->{'mod_accounting_sql'}->{'accounting_usage_cache_time'})) {
# Check if we're a boolean
if (defined(my $val = isBoolean($scfg->{'mod_accounting_sql'}{'accounting_usage_cache_time'}))) {
# If val is true, we default to the default anyway
# We're disabled
if (!$val) {
$config->{'accounting_usage_cache_time'} = undef;
}
# We *could* have a value...
} elsif ($scfg->{'mod_accounting_sql'}{'accounting_usage_cache_time'} =~ /^[0-9]+$/) {
$config->{'accounting_usage_cache_time'} = $scfg->{'mod_accounting_sql'}{'accounting_usage_cache_time'};
} else {
$server->log(LOG_NOTICE,"[MOD_ACCOUNTING_SQL] Value for 'accounting_usage_cache_time' is invalid");
}
}
}
# Log this for info sake
if (defined($config->{'accounting_usage_cache_time'})) {
$server->log(LOG_NOTICE,"[MOD_ACCOUNTING_SQL] getUsage caching ENABLED, cache time is %ds.",
$config->{'accounting_usage_cache_time'});
} else {
$server->log(LOG_NOTICE,"[MOD_ACCOUNTING_SQL] getUsage caching DISABLED");
}
}
# Function to get radius user data usage
# The 'period' parameter is optional and is the number of days to return usage for
sub getUsage
{
my ($server,$user,$packet,$period) = @_;
# Build template
my $template;
foreach my $attr ($packet->attributes) {
$template->{'request'}->{$attr} = $packet->rawattr($attr)
}
# Add user details
$template->{'user'}->{'ID'} = $user->{'ID'};
$template->{'user'}->{'Username'} = $user->{'Username'};
# Current PeriodKey, this is used for non-$period queries
my $now = DateTime->now->set_time_zone($server->{'smradius'}->{'event_timezone'});
# Query template to use below
my $queryTemplate;
# If we're doing a query for a specific period
if (defined($period)) {
# We need to switch out the query to the period query
$queryTemplate = "accounting_usage_query_period";
# Grab a clone of now, and create the start date DateTime object
my $startDate = $now->clone->subtract( 'days' => $period );
# And we add the start date
$template->{'query'}->{'PeriodKey'} = $startDate->ymd();
# If not, we just use PeriodKey as normal...
} else {
# Set the normal PeriodKey query template to use
$queryTemplate = "accounting_usage_query";
# And set the period key to this month
$template->{'query'}->{'PeriodKey'} = $now->strftime("%Y-%m");
}
# If we using caching, check how old the result is
if (defined($config->{'accounting_usage_cache_time'})) {
my ($res,$val) = cacheGetComplexKeyPair('mod_accounting_sql(getUsage)',$user->{'Username'}."/".
$template->{'query'}->{'PeriodKey'});
if (defined($val) && $val->{'CachedUntil'} > $user->{'_Internal'}->{'Timestamp-Unix'}) {
return $val;
}
}
# Replace template entries
my (@dbDoParams) = templateReplace($config->{$queryTemplate},$template);
# Fetch data
my $sth = DBSelect(@dbDoParams);
if (!$sth) {
$server->log(LOG_ERR,"[MOD_ACCOUNTING_SQL] Database query failed: %s",AWITPT::DB::DBLayer::error());
return;
}
# Our usage hash
my %usageTotals;
$usageTotals{'TotalSessionTime'} = Math::BigInt->new(0);
$usageTotals{'TotalDataInput'} = Math::BigInt->new(0);
$usageTotals{'TotalDataOutput'} = Math::BigInt->new(0);
# Pull in usage and add up
while (my $row = hashifyLCtoMC($sth->fetchrow_hashref(),
qw(AcctSessionTime AcctInputOctets AcctInputGigawords AcctOutputOctets AcctOutputGigawords)
)) {
# Look for session time
if (defined($row->{'AcctSessionTime'}) && $row->{'AcctSessionTime'} > 0) {
$usageTotals{'TotalSessionTime'}->badd($row->{'AcctSessionTime'});
}
# Add input usage if we have any
if (defined($row->{'AcctInputOctets'}) && $row->{'AcctInputOctets'} > 0) {
$usageTotals{'TotalDataInput'}->badd($row->{'AcctInputOctets'});
}
if (defined($row->{'AcctInputGigawords'}) && $row->{'AcctInputGigawords'} > 0) {
my $inputGigawords = Math::BigInt->new($row->{'AcctInputGigawords'});
$inputGigawords->bmul(GIGAWORD_VALUE);
$usageTotals{'TotalDataInput'}->badd($inputGigawords);
}
# Add output usage if we have any
if (defined($row->{'AcctOutputOctets'}) && $row->{'AcctOutputOctets'} > 0) {
$usageTotals{'TotalDataOutput'}->badd($row->{'AcctOutputOctets'});
}
if (defined($row->{'AcctOutputGigawords'}) && $row->{'AcctOutputGigawords'} > 0) {
my $outputGigawords = Math::BigInt->new($row->{'AcctOutputGigawords'});
$outputGigawords->bmul(GIGAWORD_VALUE);
$usageTotals{'TotalDataOutput'}->badd($outputGigawords);
}
}
DBFreeRes($sth);
# Convert to bigfloat for accuracy
my $totalData = Math::BigFloat->new(0);
$totalData->badd($usageTotals{'TotalDataOutput'})->badd($usageTotals{'TotalDataInput'});
my $totalTime = Math::BigFloat->new(0);
$totalTime->badd($usageTotals{'TotalSessionTime'});
# Rounding up
my %res;
$res{'TotalDataUsage'} = $totalData->bdiv(1024)->bdiv(1024)->bceil()->bstr();
$res{'TotalSessionTime'} = $totalTime->bdiv(60)->bceil()->bstr();
# If we using caching and got here, it means that we must cache the result
if (defined($config->{'accounting_usage_cache_time'})) {
$res{'CachedUntil'} = $user->{'_Internal'}->{'Timestamp-Unix'} + $config->{'accounting_usage_cache_time'};
# Cache the result
cacheStoreComplexKeyPair('mod_accounting_sql(getUsage)',$user->{'Username'}."/".$template->{'query'}->{'PeriodKey'},\%res);
}
return \%res;
}
## @log
# Try find a user
#
# @param server Server object
# @param user User object
# @param packet Radius packet
#
# @return Result
sub acct_log
{
my ($server,$user,$packet) = @_;
# Build template
my $template;
foreach my $attr ($packet->attributes) {
$template->{'request'}->{$attr} = $packet->rawattr($attr);
}
# Fix event timestamp
$template->{'request'}->{'Timestamp'} = $user->{'_Internal'}->{'Timestamp'};
# Add user details
$template->{'user'}->{'ID'} = $user->{'ID'};
$template->{'user'}->{'Username'} = $user->{'Username'};
# Current PeriodKey
my $now = DateTime->now->set_time_zone($server->{'smradius'}->{'event_timezone'});
my $periodKey = $now->strftime("%Y-%m");
# For our queries
$template->{'query'}->{'PeriodKey'} = $periodKey;
# Default to being a new period, only if we update on INTERIM or STOP do we set this to 0
my $newPeriod = 1;
#
# U P D A T E & S T O P P A C K E T
#
if ($packet->rawattr('Acct-Status-Type') eq "2" || $packet->rawattr('Acct-Status-Type') eq "3") {
# Replace template entries
my @dbDoParams = templateReplace($config->{'accounting_update_get_records_query'},$template);
# Fetch previous records of the same session
my $sth = DBSelect(@dbDoParams);
if (!$sth) {
$server->log(LOG_ERR,"[MOD_ACCOUNTING_SQL] Database query failed: %s",AWITPT::DB::DBLayer::error());
return;
}
# Convert session total gigawords into bytes
my $totalInputBytes = Math::BigInt->new($template->{'request'}->{'Acct-Input-Gigawords'});
my $totalOutputBytes = Math::BigInt->new($template->{'request'}->{'Acct-Output-Gigawords'});
$totalInputBytes->bmul(GIGAWORD_VALUE);
$totalOutputBytes->bmul(GIGAWORD_VALUE);
# Add byte counters
$totalInputBytes->badd($template->{'request'}->{'Acct-Input-Octets'});
$totalOutputBytes->badd($template->{'request'}->{'Acct-Output-Octets'});
# Packets, no conversion
my $totalInputPackets = Math::BigInt->new($template->{'request'}->{'Acct-Input-Packets'});
my $totalOutputPackets = Math::BigInt->new($template->{'request'}->{'Acct-Output-Packets'});
# We don't need bigint here, but why not ... lets keep everything standard
my $totalSessionTime = Math::BigInt->new($template->{'request'}->{'Acct-Session-Time'});
# Loop through previous records and subtract them from our session totals
while (my $sessionPart = hashifyLCtoMC($sth->fetchrow_hashref(),
qw(AcctInputOctets AcctInputPackets AcctOutputOctets AcctOutputPackets AcctInputGigawords AcctOutputGigawords
SessionTime PeriodKey)
)) {
# Make sure we treat undef values sort of sanely
$sessionPart->{'AcctInputGigawords'} //= 0;
$sessionPart->{'AcctInputOctets'} //= 0;
$sessionPart->{'AcctOutputGigawords'} //= 0;
$sessionPart->{'AcctOutputOctets'} //= 0;
$sessionPart->{'AcctInputPackets'} //= 0;
$sessionPart->{'AcctOutputPackets'} //= 0;
$sessionPart->{'AcctSessionTime'} //= 0;
# Convert the gigawords into bytes
my $sessionInputBytes = Math::BigInt->new($sessionPart->{'AcctInputGigawords'});
my $sessionOutputBytes = Math::BigInt->new($sessionPart->{'AcctOutputGigawords'});
$sessionInputBytes->bmul(GIGAWORD_VALUE);
$sessionOutputBytes->bmul(GIGAWORD_VALUE);
# Add the byte counters
$sessionInputBytes->badd($sessionPart->{'AcctInputOctets'});
$sessionOutputBytes->badd($sessionPart->{'AcctOutputOctets'});
# And packets
my $sessionInputPackets = Math::BigInt->new($sessionPart->{'AcctInputPackets'});
my $sessionOutputPackets = Math::BigInt->new($sessionPart->{'AcctOutputPackets'});
# Finally session time
my $sessionSessionTime = Math::BigInt->new($sessionPart->{'AcctSessionTime'});
# Check if this record is from an earlier period
if (defined($sessionPart->{'PeriodKey'}) && $sessionPart->{'PeriodKey'} ne $periodKey) {
# Subtract from our total, we can hit NEG!!! ... we check for that below
$totalInputBytes->bsub($sessionInputBytes);
$totalOutputBytes->bsub($sessionOutputBytes);
$totalInputPackets->bsub($sessionInputPackets);
$totalOutputPackets->bsub($sessionOutputPackets);
$totalSessionTime->bsub($sessionSessionTime);
# We need to continue this session in a new entry
$newPeriod = 1;
}
}
DBFreeRes($sth);
# Sanitize
if ($totalInputBytes->is_neg()) {
$totalInputBytes->bzero();
}
if ($totalOutputBytes->is_neg()) {
$totalOutputBytes->bzero();
}
if ($totalInputPackets->is_neg()) {
$totalInputPackets->bzero();
}
if ($totalOutputPackets->is_neg()) {
$totalOutputPackets->bzero();
}
if ($totalSessionTime->is_neg()) {
$totalSessionTime->bzero();
}
# Re-calculate
my ($inputGigawordsStr,$inputOctetsStr) = $totalInputBytes->bdiv(GIGAWORD_VALUE);
my ($outputGigawordsStr,$outputOctetsStr) = $totalOutputBytes->bdiv(GIGAWORD_VALUE);
# Conversion to strings
$template->{'query'}->{'Acct-Input-Gigawords'} = $inputGigawordsStr->bstr();
$template->{'query'}->{'Acct-Input-Octets'} = $inputOctetsStr->bstr();
$template->{'query'}->{'Acct-Output-Gigawords'} = $outputGigawordsStr->bstr();
$template->{'query'}->{'Acct-Output-Octets'} = $outputOctetsStr->bstr();
$template->{'query'}->{'Acct-Input-Packets'} = $totalInputPackets->bstr();
$template->{'query'}->{'Acct-Output-Packets'} = $totalOutputPackets->bstr();
$template->{'query'}->{'Acct-Session-Time'} = $totalSessionTime->bstr();
# Replace template entries
@dbDoParams = templateReplace($config->{'accounting_update_query'},$template);
# Update database
$sth = DBDo(@dbDoParams);
if (!$sth) {
$server->log(LOG_ERR,"[MOD_ACCOUNTING_SQL] Failed to update accounting ALIVE record: ".
AWITPT::DB::DBLayer::error());
return MOD_RES_NACK;
}
# If we updated *something* ...
if ($sth ne "0E0") {
# Be very sneaky .... if we updated something, this is obviously NOT a new period
$newPeriod = 0;
# If we updated a few things ... possibly duplicates?
if ($sth > 1) {
fixDuplicates($server, $template);
}
}
}
#
# S T A R T P A C K E T
#
# Possible aswell if we are missing a start packet for this session or for the period
#
if ($packet->rawattr('Acct-Status-Type') eq "1" || $newPeriod) {
# Replace template entries
my @dbDoParams = templateReplace($config->{'accounting_start_query'},$template);
# Insert into database
my $sth = DBDo(@dbDoParams);
if (!$sth) {
$server->log(LOG_ERR,"[MOD_ACCOUNTING_SQL] Failed to insert accounting START record: ".
AWITPT::DB::DBLayer::error());
return MOD_RES_NACK;
}
# Update first login?
if (defined($user->{'_UserDB'}->{'Users_data_get'}) && defined($user->{'_UserDB'}->{'Users_data_set'})) {
# Try get his first login
my $firstLogin = $user->{'_UserDB'}->{'Users_data_get'}($server,$user,'global','FirstLogin');
# If we don't get it, set it
if (!defined($firstLogin)) {
$user->{'_UserDB'}->{'Users_data_set'}($server,$user,'global','FirstLogin',$user->{'_Internal'}->{'Timestamp-Unix'});
}
}
}
#
# S T O P P A C K E T specifics
#
if ($packet->rawattr('Acct-Status-Type') eq "2") {
# Replace template entries
my @dbDoParams = templateReplace($config->{'accounting_stop_status_query'},$template);
# Update database (status)
my $sth = DBDo(@dbDoParams);
if (!$sth) {
$server->log(LOG_ERR,"[MOD_ACCOUNTING_SQL] Failed to update accounting STOP record: %s",AWITPT::DB::DBLayer::error());
return MOD_RES_NACK;
}
}
return MOD_RES_ACK;
}
# Resolve duplicate records
sub fixDuplicates
{
my ($server, $template) = @_;
# Replace template entries
my @dbDoParams = templateReplace($config->{'accounting_select_duplicates_query'},$template);
# Select duplicates
my $sth = DBSelect(@dbDoParams);
if (!$sth) {
$server->log(LOG_ERR,"[MOD_ACCOUNTING_SQL] Database query failed: %s",AWITPT::DB::DBLayer::error());
return;
}
# Pull in duplicates
my @IDList;
while (my $duplicates = hashifyLCtoMC($sth->fetchrow_hashref(), qw(ID))) {
push(@IDList,$duplicates->{'ID'});
}
DBFreeRes($sth);
# Loop through IDs and delete
DBBegin();
foreach my $duplicateID (@IDList) {
# Add ID list to the template
$template->{'query'}->{'DuplicateID'} = $duplicateID;
# Replace template entries
@dbDoParams = templateReplace($config->{'accounting_delete_duplicates_query'},$template);
# Delete duplicates
$sth = DBDo(@dbDoParams);
if (!$sth) {
$server->log(LOG_ERR,"[MOD_ACCOUNTING_SQL] Database query failed: %s",AWITPT::DB::DBLayer::error());
DBRollback();
return;
}
}
# Commit changes to the database
$server->log(LOG_DEBUG,"[MOD_ACCOUNTING_SQL] Duplicate accounting records deleted");
DBCommit();
return
}
# Add up totals function
sub cleanup
{
my ($server,$runForDate) = @_;
# The datetime now
my $now = DateTime->from_epoch(epoch => $runForDate)->set_time_zone($server->{'smradius'}->{'event_timezone'});
# Use truncate to set all values after 'month' to their default values
my $thisMonth = $now->clone()->truncate( to => "month" );
# Last month..
my $lastMonth = $thisMonth->clone()->subtract( months => 1 );
my $prevPeriodKey = $lastMonth->strftime("%Y-%m");
# Begin transaction
DBBegin();
$server->log(LOG_NOTICE,"[MOD_ACCOUNTING_SQL] Cleanup => Removing previous accounting summaries (if any)");
# Delete duplicate records
# NK: MYSQL SPECIFIC
my $sth = DBDo('
DELETE FROM
@TP@accounting_summary
WHERE
STR_TO_DATE(PeriodKey,"%Y-%m") >= ?',
$prevPeriodKey
);
if (!$sth) {
$server->log(LOG_ERR,"[MOD_ACCOUNTING_SQL] Cleanup => Failed to delete accounting summary record: ".
AWITPT::DB::DBLayer::error());
DBRollback();
return;
}
$server->log(LOG_NOTICE,"[MOD_ACCOUNTING_SQL] Cleanup => Generating accounting summaries");
# Select totals for last month
$sth = DBSelect('
SELECT
Username,
AcctSessionTime,
AcctInputOctets,
AcctInputGigawords,
AcctOutputOctets,
AcctOutputGigawords
FROM
@TP@accounting
WHERE
PeriodKey = ?
',
$prevPeriodKey
);
if (!$sth) {
$server->log(LOG_ERR,"[MOD_ACCOUNTING_SQL] Cleanup => Failed to select accounting record: ".
AWITPT::DB::DBLayer::error());
return;
}
# Load items into array
my %usageTotals;
while (my $row = hashifyLCtoMC($sth->fetchrow_hashref(),
qw(Username AcctSessionTime AcctInputOctets AcctInputGigawords AcctOutputOctets AcctOutputGigawords)
)) {
# check if we've seen this user, if so just add up
if (defined($usageTotals{$row->{'Username'}})) {
# Look for session time
if (defined($row->{'AcctSessionTime'}) && $row->{'AcctSessionTime'} > 0) {
$usageTotals{$row->{'Username'}}{'TotalSessionTime'}->badd($row->{'AcctSessionTime'});
}
# Add input usage if we have any
if (defined($row->{'AcctInputOctets'}) && $row->{'AcctInputOctets'} > 0) {
$usageTotals{$row->{'Username'}}{'TotalDataInput'}->badd($row->{'AcctInputOctets'});
}
if (defined($row->{'AcctInputGigawords'}) && $row->{'AcctInputGigawords'} > 0) {
my $inputGigawords = Math::BigInt->new($row->{'AcctInputGigawords'});
$inputGigawords->bmul(GIGAWORD_VALUE);
$usageTotals{$row->{'Username'}}{'TotalDataInput'}->badd($inputGigawords);
}
# Add output usage if we have any
if (defined($row->{'AcctOutputOctets'}) && $row->{'AcctOutputOctets'} > 0) {
$usageTotals{$row->{'Username'}}{'TotalDataOutput'}->badd($row->{'AcctOutputOctets'});
}
if (defined($row->{'AcctOutputGigawords'}) && $row->{'AcctOutputGigawords'} > 0) {
my $outputGigawords = Math::BigInt->new($row->{'AcctOutputGigawords'});
$outputGigawords->bmul(GIGAWORD_VALUE);
$usageTotals{$row->{'Username'}}{'TotalDataOutput'}->badd($outputGigawords);
}
# This is a new record...
} else {
# Make BigInts for this user
$usageTotals{$row->{'Username'}}{'TotalSessionTime'} = Math::BigInt->new(0);
$usageTotals{$row->{'Username'}}{'TotalDataInput'} = Math::BigInt->new(0);
$usageTotals{$row->{'Username'}}{'TotalDataOutput'} = Math::BigInt->new(0);
# Look for session time
if (defined($row->{'AcctSessionTime'}) && $row->{'AcctSessionTime'} > 0) {
$usageTotals{$row->{'Username'}}{'TotalSessionTime'}->badd($row->{'AcctSessionTime'});
}
# Add input usage if we have any
if (defined($row->{'AcctInputOctets'}) && $row->{'AcctInputOctets'} > 0) {
$usageTotals{$row->{'Username'}}{'TotalDataInput'}->badd($row->{'AcctInputOctets'});
}
if (defined($row->{'AcctInputGigawords'}) && $row->{'AcctInputGigawords'} > 0) {
my $inputGigawords = Math::BigInt->new($row->{'AcctInputGigawords'});
$inputGigawords->bmul(GIGAWORD_VALUE);
$usageTotals{$row->{'Username'}}{'TotalDataInput'}->badd($inputGigawords);
}
# Add output usage if we have any
if (defined($row->{'AcctOutputOctets'}) && $row->{'AcctOutputOctets'} > 0) {
$usageTotals{$row->{'Username'}}{'TotalDataOutput'}->badd($row->{'AcctOutputOctets'});
}
if (defined($row->{'AcctOutputGigawords'}) && $row->{'AcctOutputGigawords'} > 0) {
my $outputGigawords = Math::BigInt->new($row->{'AcctOutputGigawords'});
$outputGigawords->bmul(GIGAWORD_VALUE);
$usageTotals{$row->{'Username'}}{'TotalDataOutput'}->badd($outputGigawords);
}
}
}
$server->log(LOG_NOTICE,"[MOD_ACCOUNTING_SQL] Cleanup => Creating new accounting summaries");
# Loop through users and insert totals
foreach my $username (keys %usageTotals) {
# Convert to bigfloat for accuracy
my $totalDataOutput = Math::BigFloat->new($usageTotals{$username}{'TotalDataOutput'});
my $totalDataInput = Math::BigFloat->new($usageTotals{$username}{'TotalDataInput'});
my $totalTime = Math::BigFloat->new($usageTotals{$username}{'TotalSessionTime'});
# Rounding up
my $res;
$res->{'TotalDataInput'} = $totalDataInput->bdiv(1024)->bdiv(1024)->bceil()->bstr();
$res->{'TotalDataOutput'} = $totalDataOutput->bdiv(1024)->bdiv(1024)->bceil()->bstr();
$res->{'TotalSessionTime'} = $totalTime->bdiv(60)->bceil()->bstr();
# Do query
$sth = DBDo('
INSERT INTO
@TP@accounting_summary
(
Username,
PeriodKey,
TotalSessionTime,
TotalInput,
TotalOutput
)
VALUES
(?,?,?,?,?)
',
$username,
$prevPeriodKey,
$res->{'TotalSessionTime'},
$res->{'TotalDataInput'},
$res->{'TotalDataOutput'}
);
if (!$sth) {
$server->log(LOG_ERR,"[MOD_ACCOUNTING_SQL] Cleanup => Failed to create accounting summary record: ".
AWITPT::DB::DBLayer::error());
DBRollback();
return;
}
# Lets log
$server->log(LOG_DEBUG,"[MOD_ACCOUNTING_SQL] Cleanup => INSERT: Username = '%s', PeriodKey = '%s', ".
"TotalSessionTime = '%s', TotalInput = '%s', TotalOutput = '%s'", $username, $prevPeriodKey,
$res->{'TotalSessionTime'}, $res->{'TotalDataInput'}, $res->{'TotalDataOutput'});
}
# Commit if succeeded
DBCommit();
$server->log(LOG_NOTICE,"[MOD_ACCOUNTING_SQL] Cleanup => Accounting summaries created");
}
1;
# vim: ts=4
# Test accounting database
# Copyright (C) 2007-2009, AllWorldIT
#
# Copyright (C) 2007-2016, AllWorldIT
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
package mod_accounting_test;
package smradius::modules::accounting::mod_accounting_test;
use strict;
use warnings;
......@@ -99,15 +99,18 @@ Acct-Delay-Time: %{accounting.Acct-Delay-Time}
foreach my $attr ($packet->attributes) {
$template->{'accounting'}->{$attr} = $packet->attr($attr)
}
$template->{'user'} = $user;
if ($packet->attr('Acct-Status-Type') eq "Start") {
# Add user details
$template->{'user'}->{'ID'} = $user->{'ID'};
$template->{'user'}->{'Username'} = $user->{'Username'};
if ($packet->rawattr('Acct-Status-Type') eq "1") {
$server->log(LOG_DEBUG,"Start Packet: ".$packet->dump());
} elsif ($packet->attr('Acct-Status-Type') eq "Alive") {
} elsif ($packet->rawattr('Acct-Status-Type') eq "3") {
$server->log(LOG_DEBUG,"Alive Packet: ".$packet->dump());
} elsif ($packet->attr('Acct-Status-Type') eq "Stop") {
} elsif ($packet->rawattr('Acct-Status-Type') eq "2") {
$server->log(LOG_DEBUG,"Stop Packet: ".$packet->dump());
}
......
# CHAP authentication
# Copyright (C) 2007-2009, AllWorldIT
# Copyright (C) 2007-2015, AllWorldIT
#
# References:
# RFC1944 - PPP Challenge Handshake Authentication Protocol (CHAP)
......@@ -21,7 +21,7 @@
package mod_auth_chap;
package smradius::modules::authentication::mod_auth_chap;
use strict;
use warnings;
......
# SMRadius config information
# Copyright (C) 2007-2009, AllWorldIT
# MAC Authentication
# Copyright (C) 2007-2015, AllWorldIT
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
## @class smradius::config
# Configuration handling class
package smradius::config;
package smradius::modules::authentication::mod_auth_macauth;
use strict;
use warnings;
# Modules we need
use smradius::attributes;
use smradius::constants;
use smradius::logging;
# Exporter stuff
require Exporter;
our (@ISA,@EXPORT);
our (@ISA,@EXPORT,@EXPORT_OK);
@ISA = qw(Exporter);
@EXPORT = qw(
);
@EXPORT_OK = qw(
);
use smradius::logging;
# Plugin info
our $pluginInfo = {
Name => "MAC Authentication",
Init => \&init,
# Authentication
Authentication_try => \&authenticate,
};
# Our vars
my $config;
## @fn Init($server)
# Initialize this module with a server object
#
# @param server Server object we need to setup
sub Init
## @internal
# Initialize module
sub init
{
my $server = shift;
}
# Setup configuration
$config = $server->{'inifile'};
my $db;
$db->{'DSN'} = $config->{'database'}{'dsn'};
$db->{'Username'} = $config->{'database'}{'username'};
$db->{'Password'} = $config->{'database'}{'password'};
$db->{'enabled'} = 0;
## @authenticate
# Try authenticate user
#
# @param server Server object
# @param user User hash
# @param packet Radius packet
#
# @return Result
sub authenticate
{
my ($server,$user,$packet) = @_;
# Check we have all the config we need
if (!defined($db->{'DSN'})) {
$server->log(LOG_NOTICE,"smradius/config.pm: No 'DSN' defined in config file for 'database'");
}
$server->{'smradius'}{'database'} = $db;
}
# This is not a MAC authentication request
if ($user->{'_UserDB'}->{'Name'} ne "SQL User Database (MAC authentication)") {
return MOD_RES_SKIP;
}
$server->log(LOG_DEBUG,"[MOD_AUTH_MACAUTH] This is a MAC authentication request");
## @fn getConfig
# Get the config hash
#
# @return Hash ref of all our config items
sub getConfig
{
return $config;
return MOD_RES_ACK;
}
1;
# vim: ts=4