From: Alan T. DeKok Date: Mon, 16 Oct 2023 13:04:08 +0000 (-0400) Subject: move more functions to their own files X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6826ba9ee12ab2a8dd971001fcf75ddc85f3f048;p=thirdparty%2Ffreeradius-server.git move more functions to their own files --- diff --git a/doc/antora/modules/reference/nav.adoc b/doc/antora/modules/reference/nav.adoc index d8c39c95e64..3ae10bcd91a 100644 --- a/doc/antora/modules/reference/nav.adoc +++ b/doc/antora/modules/reference/nav.adoc @@ -63,11 +63,15 @@ ** xref:xlat/index.adoc[Dynamic Expansion] *** xref:xlat/alternation.adoc[Alternation Syntax] +*** xref:xlat/conversion.adoc[Data Conversion] *** xref:xlat/deprecated.adoc[Deprecated Functions] *** xref:xlat/file.adoc[File handling] *** xref:xlat/function.adoc[Function Syntax] +*** xref:xlat/hash.adoc[Hashing] +*** xref:xlat/interpreter.adoc[Interpreter State and Debugging] *** xref:xlat/log.adoc[Logging Functions] *** xref:xlat/protocol.adoc[Protocol Encoding and Decoding] +*** xref:xlat/string.adoc[String Handling] *** xref:xlat/builtin.adoc[Built-in Expansions] *** xref:xlat/character.adoc[Single Letter Expansions] *** xref:xlat/attribute.adoc[Attribute References] diff --git a/doc/antora/modules/reference/pages/xlat/builtin.adoc b/doc/antora/modules/reference/pages/xlat/builtin.adoc index a22a0d1f2ce..8ea9512c802 100644 --- a/doc/antora/modules/reference/pages/xlat/builtin.adoc +++ b/doc/antora/modules/reference/pages/xlat/builtin.adoc @@ -57,35 +57,6 @@ The random number is 347 ``` ==== -== Interpreter State - -The state of the interpreter can be queried via the -`%interpeter()` expansion. The individual expansions are -documented below. - -Each expansion given here can be prefixed with one or more dot (`.`) -characters. These dots allow the expansion to refer to the current -request via a `name`, or the parent request via `.name`. If there is -no parent, the expansion returns the string ``. - -=== %interpeter('module') - -The current module being executed. If the expansions is done in an -`unlang` statement and outside of any module, it returns the name of -the previous module which was executed. - -=== %interpeter('processing_stage') - -Which section of a virtual server is processing the request. - -=== %interpeter('rcode') - -The current interpreter return code, e.g. `handle`, or `ok`, etc. - -=== %interpeter('server') - -The name of the virtual server which is running the request. - == Server Configuration === %config() @@ -110,575 +81,6 @@ Server installed in /opt/freeradius Module rlm_exec.shell_escape = yes ``` -=== %client() - -Refers to a variable that was defined in the client section for the -current client. See the sections `client { ... }` in `clients.conf`. - -.Return: _string_ - -.Example - -[source,unlang] ----- -"The client ipaddr is %client(ipaddr)" ----- - -.Output - -``` -The client ipaddr is 192.168.5.9 -``` - -=== %debug() - -Dynamically change the debug level to something high, recording the old level. - -.Return: _string_ - -.Example - -[source,unlang] ----- -recv Access-Request { - if (&request.User-Name == "bob") { - "%debug(4)" - } else { - "%debug(0)" - } - ... -} ----- - -.Output (_extra informations only for that condition_) - -``` -... -(0) recv Access-Request { -(0) if (&request.User-Name == "bob") { -(0) EXPAND %debug(4) -(0) --> 2 -(0) } # if (&request.User-Name == "bob") (...) -(0) filter_username { -(0) if (&State) { -(0) ... -(0) } -... -``` - -=== %debug_attr() - -Print to debug output all instances of current attribute, or all attributes in a list. -expands to a zero-length string. - -.Return: _string_ - -.Example - -[source,unlang] ----- -recv Access-Request { - if (&request.User-Name == "bob") { - "%debug_attr(request[*])" - } - ... -} ----- - -.Output - -``` -... -(0) recv Access-Request { -(0) if (&request.User-Name == "bob") { -(0) Attributes matching "request[*]" -(0) &request.User-Name = bob -(0) &request.User-Password = hello -(0) &request.NAS-IP-Address = 127.0.1.1 -(0) &request.NAS-Port = 1 -(0) &request.Message-Authenticator = 0x9210ee447a9f4c522f5300eb8fc15e14 -(0) EXPAND %debug_attr(request[*]) -(0) } # if (&request.User-Name == "bob") (...) -... -``` - -=== %interpreter() - -Get information about the interpreter state. - -[options="header,autowidth"] -|=== -| State | Description -| `name` | Name of the instruction. -| `type` | Unlang type. -| `depth` | How deep the current stack is. -| `line` | Line number of the current section. -| `filename` | Filename of the current section. -|=== - -.Return: _string_ - -.Example - -[source,unlang] ----- -"Failure in test at line %interpreter(...filename):%interpreter(...line)" ----- - -.Output - -``` -Failure in test at line /path/raddb/sites-enaled/default:231 -``` - -== String manipulation - -=== %concat(<&ref:[idx]>, ) - -Used to join two or more attributes, separated by an optional delimiter. - -.Return: _string_ - -In most cases, `%concat(...)` is only useful inside of a dynamically -expanded string. If you need to concatenate strings together in a policy, just use `+`. - -.Example - -[source,unlang] ----- -&control += { - &Tmp-String-0 = "aaa" - &Tmp-String-0 = "bb" - &Tmp-String-0 = "c" -} - -&reply += { - &Reply-Message = "%concat(%{control.Tmp-String-0[*]}, ', ')" - &Reply-Message = "%concat(%{control.Tmp-String-0[*]}, ',')" -} ----- - -.Output - -``` -aaa, bb, c -aaa,bb,c -``` - -.Using "+" -[source,unlang] ----- -string foo - -&foo += { "a", "c", "c", "d" } # abcd - -&foo += &control.Tmp-String-0[*] ----- - - -=== %explode(<&ref>, ) - -Split an string into multiple new strings based on a delimiter. - -This expansion is the opposite of `%concat( ... )`. - -.Return: _the number exploded list of strings_. - -.Example - -[source,unlang] ----- -&control.Tmp-String-0 := "bob.toba@domain.com" - -&control.Tmp-String-1 := "%explode(&control.Tmp-String-0, '@')" - -&reply.Reply-Message := "Welcome %{control.Tmp-String-1[0]}" ----- - -.Output - -``` -Welcome bob.toba -``` - -=== %lpad(, , ) - -Left-pad a string. - -.Return: _string_ - -.Example - -[source,unlang] ----- -&control.Tmp-String-0 := "123" - -&reply.Reply-Message := "Maximum should be %lpad(%{control.Tmp-String-0}, 11, '0')" ----- - -.Output - -``` -Maximum should be 00000000123 -``` - -=== %rpad(, , ) - -Right-pad a string. - -.Return: _string_ - -.Example - -[source,unlang] ----- -&control.Tmp-String-0 := "123" - -&reply.Reply-Message := "Maximum should be %rpad(%{control.Tmp-String-0}, 11, '0')" ----- - -.Output - -``` -Maximum should be 12300000000 -``` - -=== %pairs(.[*]) - -Serialize attributes as comma-delimited string. - -.Return: _string_ - -.Example - -[source,unlang] ----- -&control.Tmp-String-0 := { "This is a string", "This is another one" } -&reply.Reply-Message := "Serialize output: %pairs(&control.[*])" ----- - -.Output - -``` -Serialize output: Tmp-String-0 = "\"This is a string\", Tmp-String-0 = \"This is another one\"" -``` - -=== %randstr( ...) - -Get random string built from character classes. - -.Return: _string_ - -.Example - -[source,unlang] ----- -&reply.Reply-Message := "The random string output is %randstr(aaaaaaaa}" ----- - -.Output - -``` -The random string output is 4Uq0gPyG -``` - -=== %tolower( ... ) - -Dynamically expands the string and returns the lowercase version of -it. This definition is only available in version 2.1.10 and later. - -.Return: _string_ - -.Example - -[source,unlang] ----- -&control.Tmp-String-0 := "CAIPIRINHA" -&reply.Reply-Message := "tolower of %{control.Tmp-String-0} is %tolower(%{control.Tmp-String-0})" ----- - -.Output - -``` -tolower of CAIPIRINHA is caipirinha -``` - -=== %toupper( ... ) - -Dynamically expands the string and returns the uppercase version of -it. This definition is only available in version 2.1.10 and later. - -.Return: _string_ - -.Example - -[source,unlang] ----- -&control.Tmp-String-0 := "caipirinha" -&reply.Reply-Message := "toupper of %{control.Tmp-String-0} is " + %toupper(%{control.Tmp-String-0}) ----- - -.Output - -``` -toupper of caipirinha is CAIPIRINHA -``` - -== Data Conversion - -=== %base64.encode( ... ) - -Encode a string using Base64. - -.Return: _string_ - -.Example - -[source,unlang] ----- -&control.Tmp-String-0 := "Caipirinha" -&reply.Reply-Message := "The base64 of %{control.Tmp-String-0} is %base64.encode(%{control.Tmp-String-0})" ----- - -.Output - -``` -The base64 of foo is Q2FpcGlyaW5oYQ== -``` - -=== %base64.decode( ... ) - -Decode a string previously encoded using Base64. - -.Return: _string_ - -.Example - -[source,unlang] ----- -&control.Tmp-String-0 := "Q2FpcGlyaW5oYQ==" -&reply.Reply-Message := "The base64.decode of %{control.Tmp-String-0} is %base64.decode(%{control.Tmp-String-0})" ----- - -.Output - -``` -The base64.decode of Q2FpcGlyaW5oYQ== is Caipirinha -``` - -=== %bin( ... ) - -Convert string to binary. - -.Return: _octal_ - -.Example - -[source,unlang] ----- -&control.Tmp-String-0 := "10" -&reply.Reply-Message := "The %{control.Tmp-String-0} in binary is %bin(%{control.Tmp-String-0})" ----- - -.Output - -``` -The 10 in binary is \020 -``` - -=== %hex( ... ) - -Convert to hex. - -.Return: _string_ - -.Example - -[source,unlang] ----- -&control.Tmp-String-0 := "12345" -&reply.Reply-Message := "The value of %{control.Tmp-String-0} in hex is %hex(%{control.Tmp-String-0})" ----- - -.Output - -``` -The value of 12345 in hex is 3132333435 -``` - -=== %urlquote( ... ) - -Quote URL special characters. - -.Return: _string_. - -.Example - -[source,unlang] ----- -&control.Tmp-String-0 := "http://example.org/" -&reply += { - &Reply-Message = "The urlquote of %{control.Tmp-String-0} is %urlquote(%{control.Tmp-String-0})" -} ----- - -.Output - -``` -The urlquote of http://example.org/ is http%3A%2F%2Fexample.org%2F -``` - -=== %urlunquote( ... ) - -Unquote URL special characters. - -.Return: _string_. - -.Example - -[source,unlang] ----- -&control.Tmp-String-0 := "http%%3A%%2F%%2Fexample.org%%2F" # Attention for the double %. -&reply += { - &Reply-Message = "The urlunquote of %{control.Tmp-String-0} is %urlunquote(%{control.Tmp-String-0})" -} ----- - -.Output - -``` -The urlunquote of http%3A%2F%2Fexample.org%2F is http://example.org/ -``` - -== Hashing and Encryption - -=== %hmacmd5( ) - -Generate `HMAC-MD5` of string. - -.Return: _octal_ - -.Example - -[source,unlang] ----- -&control.Tmp-String-0 := "mykey" -&control.Tmp-String-1 := "Caipirinha" -&reply.control.Tmp-Octets-0 := "%hmacmd5(%{control.Tmp-String-0} %{control.Tmp-String-1})" - -&reply += { - &Reply-Message = "The HMAC-MD5 of %{control.Tmp-String-1} in octets is %{control.Tmp-Octets-0}" - &Reply-Message = "The HMAC-MD5 of %{control.Tmp-String-1} in hex is %hex(control.Tmp-Octets-0)" -} ----- - -.Output - -``` -The HMAC-MD5 of Caipirinha in octets is \317}\264@K\216\371\035\304\367\202,c\376\341\203 -The HMAC-MD5 of Caipirinha in hex is 636f6e74726f6c3a546d702d4f63746574732d30 -``` - -=== %hmacsha1(, ) - -Generate `HMAC-SHA1` of string. - -.Return: _octal_ - -.Example - -[source,unlang] ----- -&control.Tmp-String-0 := "mykey" -&control.Tmp-String-1 := "Caipirinha" -&control.Tmp-Octets-0 := "%hmacsha1(%{control.Tmp-String-0}, %{control.Tmp-String-1})" - -&reply += { - &Reply-Message = "The HMAC-SHA1 of %{control.Tmp-String-1} in octets is %{control.Tmp-Octets-0}" - &Reply-Message = "The HMAC-SHA1 of %{control.Tmp-String-1} in hex is %hex(control.Tmp-Octets-0}" -} ----- - -.Output - -``` -The HMAC-SHA1 of Caipirinha in octets is \311\007\212\234j\355\207\035\225\256\372ʙ>R\"\341\351O) -The HMAC-SHA1 of Caipirinha in hex is 636f6e74726f6c3a546d702d4f63746574732d30 -``` - -=== %md5( ... ) - -Dynamically expands the string and performs an MD5 hash on it. The -result is binary data. - -.Return: _binary data_ - -.Example - -[source,unlang] ----- -&control.Tmp-String-0 := "Caipirinha" -&reply += { - &Reply-Message = "md5 of %{control.Tmp-String-0} is octal=%md5(%{control.Tmp-String-0})" - &Reply-Message = "md5 of %{control.Tmp-String-0} is hex=%hex(%md5(%{control.Tmp-String-0}))" -} ----- - -.Output - -``` -md5 of Caipirinha is octal=\024\204\013md||\230\243\3472\3703\330n\251 -md5 of Caipirinha is hex=14840b6d647c7c98a3e732f833d86ea9 -``` - -=== Other Hashing Functions - -The following hashes are supported for all versions of OpenSSL. - -* `%md2( ... }` -* `%md4( ... }` -* `%md5( ... }` -* `%sha1( ... }` -* `%sha224( ... }` -* `%sha256( ... }` -* `%sha384( ... }` -* `%sha512( ... }` - -The following hashes are supported for when OpenSSL 1.1.1 or greater -is installed. This version adds support for the `sha3` and `blake` -families of digest functions. - -* `%blake2s_256( ... )` -* `%blake2b_512( ... )` -* `%sha2_224( ... )` -* `%sha2_256( ... )` -* `%sha2_384( ... )` -* `%sha2_512( ... )` -* `%sha3_224( ... )` -* `%sha3_256( ... )` -* `%sha3_384( ... )` -* `%sha3_512( ... )` - -.Return: _octal_ - -.Example - -[source,unlang] ----- -&control.Tmp-String-0 := "Caipirinha" -&reply += { - &Reply-Message = "The md5 of %{control.Tmp-String-0} in octal is %md5(%{control.Tmp-String-0}}" - &Reply-Message = "The md5 of %{control.Tmp-String-0} in hex is %hex(%md5(%{control.Tmp-String-0}}}" -} ----- - -.Output - -``` -The md5 of Caipirinha in octal is \024\204\013md||\230\243\3472\3703\330n\251 -The md5 of Caipirinha in hex is 14840b6d647c7c98a3e732f833d86ea9 -``` - == Miscellaneous Expansions === %{0}+..+%{32} diff --git a/doc/antora/modules/reference/pages/xlat/conversion.adoc b/doc/antora/modules/reference/pages/xlat/conversion.adoc new file mode 100644 index 00000000000..c83746039f7 --- /dev/null +++ b/doc/antora/modules/reference/pages/xlat/conversion.adoc @@ -0,0 +1,130 @@ += Data Conversion + +The following functions perform conversion to/from different types of data encoding. + +== %base64.encode( ... ) + +Encode a string using Base64. + +.Return: _string_ + +.Example + +[source,unlang] +---- +&control.Tmp-String-0 := "Caipirinha" +&reply.Reply-Message := "The base64 of %{control.Tmp-String-0} is %base64.encode(%{control.Tmp-String-0})" +---- + +.Output + +``` +The base64 of foo is Q2FpcGlyaW5oYQ== +``` + +== %base64.decode( ... ) + +Decode a string previously encoded using Base64. + +.Return: _string_ + +.Example + +[source,unlang] +---- +&control.Tmp-String-0 := "Q2FpcGlyaW5oYQ==" +&reply.Reply-Message := "The base64.decode of %{control.Tmp-String-0} is %base64.decode(%{control.Tmp-String-0})" +---- + +.Output + +``` +The base64.decode of Q2FpcGlyaW5oYQ== is Caipirinha +``` + +== %bin( ... ) + +Convert string to binary. + +.Return: _octal_ + +.Example + +[source,unlang] +---- +&control.Tmp-String-0 := "10" +&reply.Reply-Message := "The %{control.Tmp-String-0} in binary is %bin(%{control.Tmp-String-0})" +---- + +.Output + +``` +The 10 in binary is \020 +``` + +== %hex( ... ) + +Convert to hex. + +.Return: _string_ + +.Example + +[source,unlang] +---- +&control.Tmp-String-0 := "12345" +&reply.Reply-Message := "The value of %{control.Tmp-String-0} in hex is %hex(%{control.Tmp-String-0})" +---- + +.Output + +``` +The value of 12345 in hex is 3132333435 +``` + +== %urlquote( ... ) + +Quote URL special characters. + +.Return: _string_. + +.Example + +[source,unlang] +---- +&control.Tmp-String-0 := "http://example.org/" +&reply += { + &Reply-Message = "The urlquote of %{control.Tmp-String-0} is %urlquote(%{control.Tmp-String-0})" +} +---- + +.Output + +``` +The urlquote of http://example.org/ is http%3A%2F%2Fexample.org%2F +``` + +== %urlunquote( ... ) + +Unquote URL special characters. + +.Return: _string_. + +.Example + +[source,unlang] +---- +&control.Tmp-String-0 := "http%%3A%%2F%%2Fexample.org%%2F" # Attention for the double %. +&reply += { + &Reply-Message = "The urlunquote of %{control.Tmp-String-0} is %urlunquote(%{control.Tmp-String-0})" +} +---- + +.Output + +``` +The urlunquote of http%3A%2F%2Fexample.org%2F is http://example.org/ +``` + +// Copyright (C) 2023 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +// This documentation was developed by Network RADIUS SAS. diff --git a/doc/antora/modules/reference/pages/xlat/hash.adoc b/doc/antora/modules/reference/pages/xlat/hash.adoc new file mode 100644 index 00000000000..7f260e4bae7 --- /dev/null +++ b/doc/antora/modules/reference/pages/xlat/hash.adoc @@ -0,0 +1,135 @@ += Hashing + +The following functions perform hashing. + +Note that the server supports insecure hashing methods such as MD5 and +SHA1. These functions are here for historical compatibility and +completeness. + +== %hmacmd5(, ) + +Generate `HMAC-MD5` of string. + +.Return: _octal_ + +.Example + +[source,unlang] +---- +&control.Tmp-String-0 := "mykey" +&control.Tmp-String-1 := "Caipirinha" +&reply.control.Tmp-Octets-0 := "%hmacmd5(%{control.Tmp-String-0} %{control.Tmp-String-1})" + +&reply += { + &Reply-Message = "The HMAC-MD5 of %{control.Tmp-String-1} in octets is %{control.Tmp-Octets-0}" + &Reply-Message = "The HMAC-MD5 of %{control.Tmp-String-1} in hex is %hex(control.Tmp-Octets-0)" +} +---- + +.Output + +``` +The HMAC-MD5 of Caipirinha in octets is \317}\264@K\216\371\035\304\367\202,c\376\341\203 +The HMAC-MD5 of Caipirinha in hex is 636f6e74726f6c3a546d702d4f63746574732d30 +``` + +== %hmacsha1(, ) + +Generate `HMAC-SHA1` of string. + +.Return: _octal_ + +.Example + +[source,unlang] +---- +&control.Tmp-String-0 := "mykey" +&control.Tmp-String-1 := "Caipirinha" +&control.Tmp-Octets-0 := "%hmacsha1(%{control.Tmp-String-0}, %{control.Tmp-String-1})" + +&reply += { + &Reply-Message = "The HMAC-SHA1 of %{control.Tmp-String-1} in octets is %{control.Tmp-Octets-0}" + &Reply-Message = "The HMAC-SHA1 of %{control.Tmp-String-1} in hex is %hex(control.Tmp-Octets-0}" +} +---- + +.Output + +``` +The HMAC-SHA1 of Caipirinha in octets is \311\007\212\234j\355\207\035\225\256\372ʙ>R\"\341\351O) +The HMAC-SHA1 of Caipirinha in hex is 636f6e74726f6c3a546d702d4f63746574732d30 +``` + +== %md5( ... ) + +Dynamically expands the string and performs an MD5 hash on it. The +result is binary data. + +.Return: _binary data_ + +.Example + +[source,unlang] +---- +&control.Tmp-String-0 := "Caipirinha" +&reply += { + &Reply-Message = "md5 of %{control.Tmp-String-0} is octal=%md5(%{control.Tmp-String-0})" + &Reply-Message = "md5 of %{control.Tmp-String-0} is hex=%hex(%md5(%{control.Tmp-String-0}))" +} +---- + +.Output + +``` +md5 of Caipirinha is octal=\024\204\013md||\230\243\3472\3703\330n\251 +md5 of Caipirinha is hex=14840b6d647c7c98a3e732f833d86ea9 +``` + +=== Other Hashing Functions + +The following hashes are supported for all versions of OpenSSL. + +* `%md2( ... }` +* `%md4( ... }` +* `%md5( ... }` +* `%sha1( ... }` +* `%sha224( ... }` +* `%sha256( ... }` +* `%sha384( ... }` +* `%sha512( ... }` + +The following hashes are supported for when OpenSSL 1.1.1 or greater +is installed. This version adds support for the `sha3` and `blake` +families of digest functions. + +* `%blake2s_256( ... )` +* `%blake2b_512( ... )` +* `%sha2_224( ... )` +* `%sha2_256( ... )` +* `%sha2_384( ... )` +* `%sha2_512( ... )` +* `%sha3_224( ... )` +* `%sha3_256( ... )` +* `%sha3_384( ... )` +* `%sha3_512( ... )` + +.Return: _octal_ + +.Example + +[source,unlang] +---- +&control.Tmp-String-0 := "Caipirinha" +&reply += { + &Reply-Message = "The md5 of %{control.Tmp-String-0} in octal is %md5(%{control.Tmp-String-0}}" + &Reply-Message = "The md5 of %{control.Tmp-String-0} in hex is %hex(%md5(%{control.Tmp-String-0}}}" +} +---- + +.Output + +``` +The md5 of Caipirinha in octal is \024\204\013md||\230\243\3472\3703\330n\251 +The md5 of Caipirinha in hex is 14840b6d647c7c98a3e732f833d86ea9 +``` + diff --git a/doc/antora/modules/reference/pages/xlat/interpreter.adoc b/doc/antora/modules/reference/pages/xlat/interpreter.adoc new file mode 100644 index 00000000000..7acdaa7a100 --- /dev/null +++ b/doc/antora/modules/reference/pages/xlat/interpreter.adoc @@ -0,0 +1,147 @@ += Interpreter + +The following functions allow inspection and/or manipulation of the `unlang` interpreter as it is running. + +== Debug Functions + +The following functions allow changing the debug level, or printing out specific lists of attributes. + +=== %debug() + +Dynamically change the debug level to something high, recording the old level. + +.Return: _string_ + +.Example + +[source,unlang] +---- +recv Access-Request { + if (&request.User-Name == "bob") { + "%debug(4)" + } else { + "%debug(0)" + } + ... +} +---- + +.Output (_extra informations only for that condition_) + +``` +... +(0) recv Access-Request { +(0) if (&request.User-Name == "bob") { +(0) EXPAND %debug(4) +(0) --> 2 +(0) } # if (&request.User-Name == "bob") (...) +(0) filter_username { +(0) if (&State) { +(0) ... +(0) } +... +``` + +=== %debug_attr() + +Print to debug output all instances of current attribute, or all attributes in a list. +expands to a zero-length string. + +.Return: _string_ + +.Example + +[source,unlang] +---- +recv Access-Request { + if (&request.User-Name == "bob") { + "%debug_attr(request[*])" + } + ... +} +---- + +.Output + +``` +... +(0) recv Access-Request { +(0) if (&request.User-Name == "bob") { +(0) Attributes matching "request[*]" +(0) &request.User-Name = bob +(0) &request.User-Password = hello +(0) &request.NAS-IP-Address = 127.0.1.1 +(0) &request.NAS-Port = 1 +(0) &request.Message-Authenticator = 0x9210ee447a9f4c522f5300eb8fc15e14 +(0) EXPAND %debug_attr(request[*]) +(0) } # if (&request.User-Name == "bob") (...) +... +``` + +== State + +The state of the interpreter can be queried via the +`%interpeter()` expansion. The individual expansions are +documented below. + +Each expansion given here can be prefixed with one or more dot (`.`) +characters. These dots allow the expansion to refer to the current +request via a `name`, or the parent request via `.name`. If there is +no parent, the expansion returns the string ``. + +For example `'filename'` is the name of the current file being +executed, while `'..filename'` is the filename of the parent request. + +== %interpeter('filename') + +Which filename is currently being executed. + +== %interpeter('line') + +The line number in the current file being executed. + +== %interpeter('processing_stage') + +Which section of a virtual server is processing the request. + + +== %interpeter('module') + +The current module being executed. If the expansions is done in an +`unlang` statement and outside of any module, it returns the name of +the previous module which was executed. + +== %interpeter('processing_stage') + +Which section of a virtual server is processing the request. + +== %interpeter('rcode') + +The current interpreter return code, e.g. `handle`, or `ok`, etc. + +== %interpeter('server') + +The name of the virtual server which is running the request. + +=== %client() + +Refers to a variable that was defined in the client section for the +current client. See the sections `client { ... }` in `clients.conf`. + +.Return: _string_ + +.Example + +[source,unlang] +---- +"The client ipaddr is %client(ipaddr)" +---- + +.Output + +``` +The client ipaddr is 192.168.5.9 +``` + +// Copyright (C) 2023 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +// This documentation was developed by Network RADIUS SAS. diff --git a/doc/antora/modules/reference/pages/xlat/string.adoc b/doc/antora/modules/reference/pages/xlat/string.adoc new file mode 100644 index 00000000000..1abf5152d8b --- /dev/null +++ b/doc/antora/modules/reference/pages/xlat/string.adoc @@ -0,0 +1,194 @@ += String manipulation + +The following functions perform string manipulation. + +== %concat(<&ref:[idx]>, ) + +Used to join two or more attributes, separated by an optional delimiter. + +.Return: _string_ + +In most cases, `%concat(...)` is only useful inside of a dynamically +expanded string. If you need to concatenate strings together in a policy, just use `+`. + +.Example + +[source,unlang] +---- +&control += { + &Tmp-String-0 = "aaa" + &Tmp-String-0 = "bb" + &Tmp-String-0 = "c" +} + +&reply += { + &Reply-Message = "%concat(%{control.Tmp-String-0[*]}, ', ')" + &Reply-Message = "%concat(%{control.Tmp-String-0[*]}, ',')" +} +---- + +.Output + +``` +aaa, bb, c +aaa,bb,c +``` + +.Using "+" +[source,unlang] +---- +string foo + +&foo += { "a", "c", "c", "d" } # abcd + +&foo += &control.Tmp-String-0[*] +---- + +== %explode(<&ref>, ) + +Split an string into multiple new strings based on a delimiter. + +This expansion is the opposite of `%concat( ... )`. + +.Return: _the number exploded list of strings_. + +.Example + +[source,unlang] +---- +&control.Tmp-String-0 := "bob.toba@domain.com" + +&control.Tmp-String-1 := "%explode(&control.Tmp-String-0, '@')" + +&reply.Reply-Message := "Welcome %{control.Tmp-String-1[0]}" +---- + +.Output + +``` +Welcome bob.toba +``` + +== %lpad(, , ) + +Left-pad a string. + +.Return: _string_ + +.Example + +[source,unlang] +---- +&control.Tmp-String-0 := "123" + +&reply.Reply-Message := "Maximum should be %lpad(%{control.Tmp-String-0}, 11, '0')" +---- + +.Output + +``` +Maximum should be 00000000123 +``` + +== %rpad(, , ) + +Right-pad a string. + +.Return: _string_ + +.Example + +[source,unlang] +---- +&control.Tmp-String-0 := "123" + +&reply.Reply-Message := "Maximum should be %rpad(%{control.Tmp-String-0}, 11, '0')" +---- + +.Output + +``` +Maximum should be 12300000000 +``` + +== %pairs(.[*]) + +Serialize attributes as comma-delimited string. + +.Return: _string_ + +.Example + +[source,unlang] +---- +&control.Tmp-String-0 := { "This is a string", "This is another one" } +&reply.Reply-Message := "Serialize output: %pairs(&control.[*])" +---- + +.Output + +``` +Serialize output: Tmp-String-0 = "\"This is a string\", Tmp-String-0 = \"This is another one\"" +``` + +== %randstr( ...) + +Get random string built from character classes. + +.Return: _string_ + +.Example + +[source,unlang] +---- +&reply.Reply-Message := "The random string output is %randstr(aaaaaaaa}" +---- + +.Output + +``` +The random string output is 4Uq0gPyG +``` + +== %tolower( ... ) + +Dynamically expands the string and returns the lowercase version of +it. This definition is only available in version 2.1.10 and later. + +.Return: _string_ + +.Example + +[source,unlang] +---- +&control.Tmp-String-0 := "CAIPIRINHA" +&reply.Reply-Message := "tolower of %{control.Tmp-String-0} is %tolower(%{control.Tmp-String-0})" +---- + +.Output + +``` +tolower of CAIPIRINHA is caipirinha +``` + +== %toupper( ... ) + +Dynamically expands the string and returns the uppercase version of +it. This definition is only available in version 2.1.10 and later. + +.Return: _string_ + +.Example + +[source,unlang] +---- +&control.Tmp-String-0 := "caipirinha" +&reply.Reply-Message := "toupper of %{control.Tmp-String-0} is " + %toupper(%{control.Tmp-String-0}) +---- + +.Output + +``` +toupper of caipirinha is CAIPIRINHA +``` +