From: Jorge Pereira Date: Tue, 11 Aug 2020 23:13:56 +0000 (-0300) Subject: tacacs: Update raddb/sites-available/tacacs X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ef8ffd64158d1191c99b04746533f35ce345481f;p=thirdparty%2Ffreeradius-server.git tacacs: Update raddb/sites-available/tacacs --- diff --git a/raddb/sites-available/tacacs b/raddb/sites-available/tacacs index 6b8dec309c9..bece13dec12 100644 --- a/raddb/sites-available/tacacs +++ b/raddb/sites-available/tacacs @@ -9,258 +9,247 @@ ###################################################################### server tacacs { + # + # namespace:: Needs to be "tacacs" for TACACS+ functionality. + # namespace = tacacs listen { - ipaddr = * + # + # type:: The type of packet to accept. + # + # Multiple types can be accepted by using multiple + # lines of `type = ...`. + # + # As described in RFC https://tools.ietf.org/id/draft-ietf-opsawg-tacacs-07.html#rfc.section.5, + # the packet types are: + # + type = Authentication-Start + type = Authentication-Continue +# type = Authorization-Request +# type = Accounting-Request + + # + # transport:: The transport protocol. + # + # Only `tcp` is allowed. + # transport = tcp + # + # ## Protocols + # + # For now, only TCP is supported. + # + # tcp { ... }:: TCP is configured here. + # tcp { - # Port on which to listen. - # Allowed values are: - # integer port number - # 49 is the default TACACS+ port. - port = 49 + # + # port:: The port where we accept packets. + # + # The port should be 49 for a production network. + # + port = 4900 - # Type of packets to listen for. Here, it is TACACS+. - type = tacacs + # + # ipaddr:: The IP address where we accept packets. + # + ipaddr = * - # Some systems support binding to an interface, in addition - # to the IP address. This feature isn't strictly necessary, - # but for sites with many IP addresses on one interface, - # it's useful to say "listen on all addresses for - # eth0". # - # If your system does not support this feature, you will - # get an error if you try to use it. + # interface:: Interface to bind to. # - # interface = eth0 - } +# interface = eth0 + + # + # max_packet_size:: Our max packet size. may be different from the parent. + # +# max_packet_size = 4096 - type = Authentication - type = Authorization + # + # recv_buff:: How big the kernel's receive buffer should be. + # +# recv_buff = 1048576 + + # + # send_buff:: How big the kernel's send buffer should be. + # +# send_buff = 1048576 + + # + # src_ipaddr:: IP we open our socket on. + # +# src_ipaddr = "" + } } # - # This section is called when it receives an Authentication. + # ## Authentication-Start # - recv Authentication { - if (&TACACS-Sequence-Number > 1) { - update request { - TACACS-Authentication-Type = &session-state:TACACS-Authentication-Type - } - } - # draft-ietf-opsawg-tacacs section 4.4.2 + # + # ### Recv + # + recv Authentication-Start { switch &TACACS-Authentication-Type { - # ASCII is very generic and driven via unlang so go wild! - case "ASCII" { - if (&TACACS-Sequence-Number == 1) { - update request { - &User-Name = &TACACS-User-Name - } - } else { - update request { - User-Name = &session-state:User-Name - User-Password = &session-state:User-Password - } - } - - if (!&User-Name) { - if (&TACACS-User-Message) { - update request { - &User-Name = &TACACS-User-Message - &TACACS-User-Message !* "*" - } - } else { - update reply { - TACACS-Authentication-Status = Get-User - TACACS-Server-Message = "username: " - } - handled - } - } - if (!&User-Password) { - if (&TACACS-User-Message) { - update request { - &User-Password = &TACACS-User-Message - &TACACS-User-Message !* "*" - } - } else { - update reply { - TACACS-Authentication-Status = Get-Pass - TACACS-Server-Message = "password: " - } - handled - } - } - #if (&User-Name && &User-Password) { - # if (!&TACACS-User-Message) { - # update reply { - # TACACS-Authentication-Status = Get-Data - # TACACS-Authentication-Flags = No-Echo - # TACACS-Server-Message = "pin: " - # } - # handled - # } - # if (&TACACS-User-Message != "1234") { - # reject - # } - #} - } - case "PAP" { - if (&TACACS-Sequence-Number == 1) { - if (!&TACACS-User-Name) { - update reply { - &TACACS-Server-Message = "missing User-Name field" - } - invalid - } - - update request { - &User-Name = &TACACS-User-Name - &User-Password = &TACACS-Data - } - } else { - update request { - User-Name = &session-state:User-Name - } - } - - if (!&User-Password) { - if (&TACACS-User-Message) { - update request { - &User-Password = &TACACS-User-Message - } - } else { - update reply { - TACACS-Authentication-Status = Get-Pass - TACACS-Server-Message = "password: " - } - handled - } - } - } - case "CHAP" { - if (&TACACS-Sequence-Number > 1) { - invalid + case PAP { + update request { + &User-Name := &TACACS-User-Name + &User-Password := &TACACS-Data + &Cleartext-Password := &TACACS-Data } - if (&TACACS-User-Name && &TACACS-Data =~ /^(.)(.{16})(.{16})$/) { - update request { - &User-Name = &TACACS-User-Name - &CHAP-Challenge = "%{2}" - &CHAP-Password = "%{1}%{3}" - } - } else { - update reply { - &TACACS-Server-Message = "missing User-Name and/or Data fields" - } - invalid - } + # + # Read what used to be the `users` file. Since v3, this file + # is located in `mods-config/files/authorize`. + # + files + + # + # Look in an SQL database. The schema of the database is + # meant to mirror the `users` file. For a full description + # of the module behavior, please see + # https://wiki.freeradius.org/modules/Rlm_sql + # + -sql + + # + # The `pap` module will set `TACACS-Authentication-Type := PAP` if the + # packet contains a `User-Password` attribute. The module + # does this only if the `Auth-Type` attribute has not already + # been set. + # + # The `pap` module is also responsible for "normalizing" the + # various kinds of "known good" passwords. + # e.g. `NT-Password` may come as a 16 byte blob, or as a + # 32-byte hex string, or as a base-64 encoded string. The + # `pap` module will look for common variations of password + # encoding, and convert them all to a normal form. + # + # This module should be listed last, so that the other + # modules get a chance to set TACACS-Authentication-Type for themselves. + # + pap } - case "MSCHAP" { # UNTESTED - if (&TACACS-Sequence-Number > 1) { - invalid - } - if (&TACACS-User-Name && &TACACS-Data =~ /^(.)(.{8})(.{50})$/) { - update request { - &User-Name = &TACACS-User-Name - &MS-CHAP-Challenge = "%{2}" - &MS-CHAP-Response = "%{1}%{3}" - } - } else { - update reply { - &TACACS-Server-Message = "missing User-Name and/or Data fields" - } - invalid - } - } - case "MSCHAPv2" { # UNTESTED - if (&TACACS-Sequence-Number > 1) { - invalid - } - - if (&TACACS-User-Name && &TACACS-Data =~ /^(.)(.{16})(.{50})$/) { - update request { - &User-Name = &TACACS-User-Name - &MS-CHAP-Challenge = "%{2}" - &MS-CHAP2-Response = "%{1}%{3}" - } - } else { - update reply { - &TACACS-Server-Message = "missing User-Name and/or Data fields" - } - invalid - } - } - case { - update reply { - &TACACS-Server-Message = "unsupported authentication type" - } - invalid - } + # + # For now the 'chap' is only supported with RADIUS + # +# case CHAP { +# chap +# } } - files + -sql + } - mschap + authenticate PAP { + pap + } + authenticate CHAP { chap - - pap } # - # This section is called when it sends an Authentication. + # ### Send # - send Authentication { - switch &TACACS-Authentication-Type { - case "ASCII" { - update session-state { - &TACACS-Authentication-Type := &TACACS-Authentication-Type - &User-Name := &User-Name - &User-Password := &User-Password - } - } - case { - update reply { - &reply:TACACS-Server-Message = &reply:Reply-Message - } - } - } + send Authentication-Start-Reply { +# if (&TACACS-Authentication-Status == Pass) { +# update reply { +# &TACACS-Server-Message := "Hello %{TACACS-User-Name}" +# } +# } } - recv Authorization { - update config { - &Auth-Type = Accept - } + # + # ## Authentication-Continue + # + + # + # ### Recv + # + recv Authentication-Continue { + # + # https://tools.ietf.org/id/draft-ietf-opsawg-tacacs-07.html#rfc.section.4.3 + # + "%{TACACS-Authentication-Continue-Flags}" + "%{TACACS-User-Message}" + "%{TACACS-Data}" } - send Authorization { + # + # ### Send + # + send Authentication-Continue-Reply { +# if (&TACACS-Authentication-Status == Pass) { +# update reply { +# &TACACS-Server-Message := "Hello %{TACACS-User-Name}" +# } +# } } - recv Accounting-Request { - update config { - &Auth-Type = Accept - } + # + # ## Authorization + # + + # + # ### Recv + # + recv Authorization-Request { + "%{TACACS-Authentication-Method}" + "%{TACACS-Privilege-Level}" + "%{TACACS-Authentication-Type}" + "%{TACACS-Authentication-Service}" + "%{TACACS-User-Name}" + "%{TACACS-Client-Port}" + "%{TACACS-Remote-Address}" + "%{TACACS-ArgumentList}" } - send Accounting-Response { + # + # ### Send + # + send Authorization-Response { + update reply { + &TACACS-Authorization-Status := Pass-Add + &TACACS-Server-Message := "authorization-response-server" + &TACACS-Data := "authorization-response-data" + &TACACS-ArgumentList := "key1=var1" + } } - # Proxying of TACACS+ requests is NOT supported. + # + # ## Accounting + # - authenticate mschap { - mschap + # + # ### Recv + # + recv Accounting-Request { + "%{TACACS-Accounting-Flags}" + "%{TACACS-Authentication-Method}" + "%{TACACS-Privilege-Level}" + "%{TACACS-Authentication-Type}" + "%{TACACS-Authentication-Service}" + "%{TACACS-User-Name}" + "%{TACACS-Client-Port}" + "%{TACACS-Remote-Address}" + "%{TACACS-ArgumentList}" } - authenticate chap { - chap + # + # ### Send + # + send Accounting-Response { + update reply { + &TACACS-Accounting-Status := Success + &TACACS-Server-Message := "acct-response-server" + &TACACS-Data := "acct-response-data" + } } - authenticate pap { - pap - } + # + # NOTE: Proxying of TACACS+ requests is NOT supported. + # }