OUR SITES NetworkRADIUS FreeRADIUS

File Handling functions

The file handling functions allow for a limited number of operations on files.

The filenames can be taken from tainted sources, in which cases special characters such as ‘/’ and ‘$’ are escaped. Any special character is replaced with an underscore, followed by the hex value of the character. Valid UTF-8 characters are allowed.

For example, the tainted string user@freeradius.org/.. will turn into the filename user@freeradius.org_2f... This operation renders the filename "safe" for operations on the local file system. It is not possible for tainted data to create files, or to perform directory traversal attacks.

%file.escape(string)

Return: string

This function returns an escaped or "safe" version of the input string.

In some cases, as when using %exec(…​), it is impossible to determine which arguments are filenames, and which are simple strings. This function allows the server to safely pass in a filename to external programs.

The returned filename is guaranteed to be safe to use. Any portion of the filename which is taken from a "safe" source (i.e. configuration files, etc. controlled by an administrator) is used as-is. Any portion of the filename which is taken from an "unsafe" source (i.e. network apckets) is escaped. The result is that characters like / in unsafe inputs cannot be used to perform directory traversal attacks.

Example 1. Safely pass a filename to %exec(…​)
&filename = "${logdir}/" + %file.escape(%{User-Name})

%exec("/bin/rm", %{filename})

%file.exists(string)

Return: bool

This function returns true if a file exists, or false if the file does not exist.

Example 2. Checking if a file exists
if %file.exists("/var/log/radius.log") {
	# do things...
}

%file.head(string)

Return: string

This function returns the first line of the file. If the file does not exist, or if the line is more than 256 characters in length, it fails and nothing is returned.

Example 3. Returning the first line of a file
string line

&line := %file.head("/var/log/radius.log")

%file.rm(string)

Return: bool

This function removes a file. If the file exists and could be removed, it returns true. Otherwise if the file does not exist, or if the file could not be removed, it returns `false.

Example 4. Removing a file
if (%file.size("/var/log/radius.log") > (((uint64)1) << 20)) {
	%file.rm("/var/log/radius.log")
}

%file.size(string)

Return: uint64

This function checks the size of a file.

Example 5. Checking the size of a file
if (%file.size("/var/log/radius.log") > (((uint64)1) << 20)) {
	%log.info("The log file is getting large!")
}

%file.tail(string, [ uint32 ])

Return: string

This function returns the last line of the file. If the file does not exist, or if the line is more than 256 characters in length, it fails and nothing is returned.

The function takes an optional second argument, which is the number of lines which should be returned. The maximum number of lines which will be returned is limited to 15.

Example 6. Returning the first line of a file
string line

&line := %file.tail("/var/log/radius.log")

&line := %file.tail("/var/log/radius.log", 2)