From: Matthew Newton Date: Thu, 27 Jul 2023 11:45:42 +0000 (+0100) Subject: backport some documentation from v4 X-Git-Tag: release_3_2_4~195 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3c2eea1540d398efd3917a4fc94f003431c88093;p=thirdparty%2Ffreeradius-server.git backport some documentation from v4 --- diff --git a/doc/antora/modules/concepts/nav.adoc b/doc/antora/modules/concepts/nav.adoc new file mode 100644 index 00000000000..493b9566417 --- /dev/null +++ b/doc/antora/modules/concepts/nav.adoc @@ -0,0 +1,6 @@ +* xref:index.adoc[Concepts] +** General +*** xref:aaa.adoc[AAA] +** Modules +*** LDAP +**** xref:modules/ldap/authentication.adoc[Authentication] diff --git a/doc/antora/modules/concepts/pages/aaa.adoc b/doc/antora/modules/concepts/pages/aaa.adoc new file mode 100644 index 00000000000..294305cb5b2 --- /dev/null +++ b/doc/antora/modules/concepts/pages/aaa.adoc @@ -0,0 +1,60 @@ += AAA + +== Authorization, Authentication, and Accounting request handling + +There are a lot of questions about misconfigured FreeRADIUS servers +because of misunderstanding of FreeRADIUS operations. This document +explains how the server operates. + +Normally there are two steps in processing an authentication request +coming from a NAS in FreeRADIUS: authorization and authentication. +If we use FreeRADIUS as a proxy to re-send the request to another +RADIUS server there will be additional steps. + +=== Authorization + +Authorization is the process of finding and returning information +about what the user is allowed to do. For example, finding out what +kind of authentication methods they are allowed to run, and what VLAN +the user should be placed into. + +Authorization modules generally "get data" from somewhere, +e.g. `ldap`, `sql`, `files`, etc. + +The authentication method is usually determined when the server gets +the users credentials from a database. Once the credentials are +available, the server can authenticate the user. + +=== Authentication + +Authentication is simply a process of comparing user’s credentials in +request with the "known good" credentials retrieved from a +database. Authentication usually deals with password +encryption. The modules `pap`, `chap`, `mschap`, etc. do authentication. + +Some modules do both authentication and limited authorization. For +example, the `mschap` module authenticates MS-CHAP credentials, but it +may also be used as an authorization module, which verifies that +request contains `MS-CHAP` related attribute. If so, the module +instructs the server to use `mschap` for authentication, too + +These dual modules are usually related to protocol-specific +attributes, such as the `pap` module for the `User-Password` +attribute, `chap` for `CHAP-Password`, `mschap` for `MS-CHAP-*`, etc. + +=== Request Processing + +When the server processes requests, it manages four +xref:unlang:list.adoc[attribute lists]: + +`request`:: attributes taken from the received packet + +`reply`:: attributes which will be sent in the reply + +`control`:: attributes used to control how the server operates. These are never sent in a packet + +`session-state`:: attributes which are saved and restroed across multiple request / reply exchanges. + +All of these lists are available to all modules. All of these +lists are available in xref:unlang:index.adoc[Unlang]. + diff --git a/doc/antora/modules/concepts/pages/index.adoc b/doc/antora/modules/concepts/pages/index.adoc new file mode 100644 index 00000000000..f2bc25f36fa --- /dev/null +++ b/doc/antora/modules/concepts/pages/index.adoc @@ -0,0 +1,8 @@ += Concepts + +This section documents concerning the protocols and modules used by the +FreeRADIUS server. + +It intended to provide more theoretical information about particular subjects +than would be appropriate to include inline in module configurations or as +sidebars in howto guides. diff --git a/doc/antora/modules/concepts/pages/modules/ldap/authentication.adoc b/doc/antora/modules/concepts/pages/modules/ldap/authentication.adoc new file mode 100644 index 00000000000..edc553e80af --- /dev/null +++ b/doc/antora/modules/concepts/pages/modules/ldap/authentication.adoc @@ -0,0 +1,203 @@ +== Authenticating Users with LDAP + +Please be aware the FreeRADIUS is an AAA server, and LDAP +is a _database_. This separation of roles means that FreeRADIUS +supports multiple kinds of authentication protocols such as `PAP`, +`CHAP`, `MS-CHAP`, etc. An LDAP database supports only one +authentication method: "bind as user". This authentication method is +compatible only with PAP. + +Our recommendation is to use LDAP as a database. FreeRADIUS should +read the "known good" password from LDAP, and then use that +information to authenticate the user. It is almost always wrong to +use the LDAP "bind as user" method for authenticating users. + +The only caveat to the above recommendation is Active Directory. For +"security" reasons, Active Directory will not return the "known good" +password to FreeRADIUS over a standard LDAP query. Therefore when +Active Directory is used, the choices are: + +PAP:: +Use "bind as user" + +MS-CHAP:: +Use xref:raddb:mods-available/ntlm_auth.adoc[`ntlm`] or xref:raddb:mods-available/winbind.adoc[`winbind`]. + +Due to the limitations of Active Directory, There are unfortunately no +other possible choices. + +== LDAP Security Recommendations + +The credentials (username *and* password) for FreeRADIUS to use to +connect to your LDAP server(s) should be secure. We make the +following recommendations for LDAP "best practices" security. + +* Create a dedicated account for use by FreeRADIUS + +* Ensure that this account does not have administrator access + +* Ensure that this account is read-only, and has no write permissions + +* Start by using 'simple authentication' instead of + https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer[SASL]. + The SASL protocol should be attempted only after 'simple + authentication' has been verified to work. + +* Use TLS for connecting between FreeRADIUS and the LDAP server. See + the `tls` sub-section of the default `ldap` module for instructions + +* When storing RADIUS user profiles (quotas, `Simultaneous-Use` flags, + access time restrictions, etc) in LDAP, the LDAP schema + `doc/schemas/ldap/openldap/freeradius-radius.schema` must first be imported + into the LDAP server. + +== Authentication method compatibility + +The LDAP module is compatible a few different kinds of authentication +methods. Note that we say _compatible_, and not _supports_. LDAP +servers are databases, and do not support authentication protocols +such as CHAP, MS-CHAP, or EAP. + +PAP:: +The user supplies a `User-Password` (plaintext or EAP-TTLS/PAP) ++ +FreeRADIUS reads the "known good" password from LDAP, and compares +that to what the user entered. + +Bind as user:: +The user supplies a `User-Password` (plaintext or EAP-TTLS/PAP) ++ +FreeRADIUS uses that password to "bind as the user" to LDAP, using the +supplied `User-Name` and `User-Password. If the bind is successfull, +the user is authenticated. Otherwise, authentication fails. + +CHAP:: +The user supplies a `CHAP` password attribute. ++ +FreeRADIUS reads the "known good" password from LDAP in cleartext, and +compares that to what the user entered. + +MS-CHAP:: +The user supplies a `MS-CHAP` password attribute. Either as +MS-CHAPv2, or as PEAP/MSCHAPv2, or as EAP-TTLS/MS-CHAPv2. ++ +FreeRADIUS reads the "known good" password from LDAP in cleartext, or +as an NT hash, and compares that to what the user entered. + +All of above authentication methods other than "bind as user" require +that FreeRADIUS obtain the `userPassword` field from LDAP. If that +field is not returned to FreeRADIUS, then normal authentication is +impossible. Either FreeRADIUS has to be configured to use "bind as +user" for authentication, or the LDAP database has to be updated to +return the `userPassword` field to FreeRADIUS. This change usually +involves giving the FreeRADIUS "read-only" user permission to read the +`userPassword` field. + +Again, the best method is to test authentication is with the +xref:howto:modules/ldap/ldapsearch/index.adoc[ldapsearch] tool. +These tests *must* be run prior to configuring FreeRADIUS. We strongly +recommend having the LDAP database return the `userPassword` field to +FreeRADIUS, so that FreeRADIUS can authenticate the user. + +We also strongly recommend that the passwords be stored in LDAP as +cleartext. Otherwise, the only authentication methods that will work +are PAP and EAP-TTLS/PAP. The next section explains these issues in +more detail. + +== Password Storage Methods + +If the `userPassword` field is returned from LDAP to FreeRADIUS, that +information can be stored in a number of different formats: + +* the value can be cleartext +* the value can be prepended with a string enclosed by braces, such as with `{crypt}` or `{ssha3}`. +* the value can be have a suffix of `::`, in which case the password is generally a https://en.wikipedia.org/wiki/Base64[base64] encoded version of the real password + +TIP: Base64 values can be decoded via the command: `printf "%s" +"VALUE" | base64 -d` + +FreeRADIUS is capable of understanding and parsing all of the above +formats. There is sufficient information in the password values to +determine what format it is in (base64, binary, or text), and what +password "encryption" mechanism has been used (crypt, MD5, SHA, SSHA2, +SHA3, etc). All that is necessary is that the +xref:raddb:mods-available/ldap.adoc[ldap module] be configured to map +the `userPassword` LDAP field to the `&control.Password.With-Header` +attribute in FreeRADIUS. FreeRADIUS will then "do the right thing" to +authenticate the user. + +This mapping is done in the default module configuration. There are +no additional changes required for FreeRADIUS to correctly read and +decode the `userPassword` field from LDAP. Please see the +xref:raddb:mods-available/pap.adoc[pap module] for a full list of +supported password "encryption" formats. + +== Additional Considerations + +There are some major caveats with the above authentication methods. +The first is that we *strongly recommend* against using "bind as +user". This process is slow, and causes unnecessary churn in the +connections used to contact the LDAP server. Further, the "bind as +user" process works _only_ when a `User-Password attribute exists in +the request. If any other authentication type is used in the request, +then the "bind as user" _will not work_. There is no amount of +"fixing" things or configuration changes which will make it work. + +The second caveat is that the `CHAP` authentication type works _only_ +when a "clear text" password is stored in the LDAP database. The +`CHAP` calclulations are designed around having access to the "clear +text" password. It is impossible to use any "encrypted" or "hashed" +passwords with `CHAP`. + +The third caveat is that the `MS-CHAP` authentication type works +_only_ when a "clear text" password or "NT hashed" passwords which are +stored in the LDAP database. The `MS-CHAP` calculations are designed +around having access to "known good" passwords in those formats. It +is impossible to use any other kind of "encrypted" or "hashed" +passwords with `MS-CHAP`. + +The final caveat is that when the LDAP database contains "encrypted" +or "hashed" passwords, the _only_ authentication type which is +compatible with those passwords is PAP. i.e. when the `User-Password` +is supplied to FreeRADIUS. + +For recommendations on password storage methods in LDAP, please see +the LDAP +https://openldap.org/doc/admin24/security.html#Password%20Storage[password +storage] page. Please note that the recommendations there are made +for LDAP security, and pay no attention to the caveats described +above. When both RADIUS and LDAP are used together, then the +requirements of _both_ systems must be met in order for them to work +together. In many cases, a naive approach to LDAP security will +prevent RADIUS from working. + +The issue of a database storing passwords in clear-text has to be +balanced against the users sending clear-text passwords in +authentication protocols. While those passwords are protected by TLS +(EAP-TTLS) or by RADIUS (in it's own "encryption" mechanism), it is +generally better to use a stronger authentication method than just +PAP. + +In the end, there is no perfect solution to security requirements. +The choice may be either to give up on using a particular +authentication method, or to relax the security requirements on LDAP +and on password storage. The final decision as to which choice is +best can only be made by a local administrator. + +== Integrating Novell eDirectory with FreeRADIUS + +You can integrate Novell eDirectoryTM 8.7.1 or later with FreeRADIUS +1.0.2 onwards to allow wireless authentication for eDirectory users. By +integrating eDirectory with FreeRADIUS, you can do the following: + +* Use universal password for RADIUS authentication. Universal password +provides single login and authentication for eDirectory users. +Therefore, the users need not have a separate password for RADIUS and +eDirectory authentication. +* Enforce eDirectory account policies for users. The existing eDirectory +policies on the user accounts can still be applied even after +integrating with RADIUS. Also, you can make use of the intruder lockout +facility of eDirectory by logging the failed logins into eDirectory. + +For configuration information please refer to the Novell documentation +https://www.netiq.com/documentation/edir_radius/ diff --git a/doc/antora/modules/developers/nav.adoc b/doc/antora/modules/developers/nav.adoc new file mode 100644 index 00000000000..ed6962a7345 --- /dev/null +++ b/doc/antora/modules/developers/nav.adoc @@ -0,0 +1,7 @@ +* xref:index.adoc[Developers] +** xref:bugs.adoc[Bugs] +** xref:coding-methods.adoc[Coding Methods] +** xref:coverage.adoc[Code Coverage] +** xref:profile.adoc[Profiling] +** xref:contributing.adoc[Contributing] +** xref:release-method.adoc[Release Method] diff --git a/doc/antora/modules/developers/pages/bugs.adoc b/doc/antora/modules/developers/pages/bugs.adoc new file mode 100644 index 00000000000..b63329c0bbe --- /dev/null +++ b/doc/antora/modules/developers/pages/bugs.adoc @@ -0,0 +1,194 @@ += Bugs + +== Introduction + +The FreeRADIUS web site is at https://freeradius.org/, and most +information referenced in this document can be found there. + +This document is primarily for non-developers of the FreeRADIUS +server. If you are able to patch the code to work correctly, then +we invite you to join the development list to discuss it. If +you’re the type who know little about how to code, then this is +the place for you! + +== You found a bug + +Where the server terminates ungracefully due to a bus error, +segmentation violation, or other memory error, you should create a new +issue in the issue tracker https://bugs.freeradius.org/, including +information from the debugging sections below. + +For any other issues, you should first discuss them on the +https://freeradius.org/support/[FreeRADIUS users list], to +see if anyone can reproduce them. Often there’s a simple explanation of +why the server behaves as it does, and it’s not necessarily a bug in the +code, so browse the lists’ archives of the last two months, and if you +don’t see messages about it, ask! + +If the behavior is correct but confusing, we think that’s a bug too, and +you should file a bug against our documentation. + +For more information about the users list, the lists’ archives and the +faq, please visit https://www.freeradius.org/list/users.html Please make +sure to READ and RESPECT the house-rules. You will get much better +response and much faster if you do! + +== Core dumps + +If the server (or one of the accompanying programs) core dumps, then you +should rebuild the server as follows: + +``` +$ ./configure --enable-developer +$ make +$ make install +``` + +and then run the program again. You may have to to enable core dumps, +via: + +``` +$ ulimit -c unlimited +``` + +When it core dumps, do: + +``` +$ gdb /path/to/executable /path/to/core/file +``` + +Enable logging in `gdb` via the following commands: + +``` +(gdb) set logging file gdb-radiusd.log +(gdb) set logging on +``` + +and follow the instructions in the proceeding section. + +You can also enable the `panic_action` given in +`raddb/radiusd.conf`. See the comments in that file for more details +about automatically collecting gdb debugging information when the server +crashes. + +== Debugging a live server + +If you can’t get a core dump, or the problem doesn’t result in a core +dump, you may have to run the server under gdb. To do this, ensure that +you have symbols in the binaries (i.e. a 'non-stripped' binary) by +re-building the server as described in the previous section. Then, run +the server under gdb as follows: + +``` +$ gdb radiusd +``` + +Enable logging in `gdb` via the following commands: + +``` +(gdb) set logging file gdb-radiusd.log +(gdb) set logging on +``` + +Tell `gdb` to pass any necessary command-line arguments to the server: + +``` +(gdb) set args ... +``` + +Where the ``…'' are the command-line arguments you normally pass to +radiusd. For debugging, you probably want to do: + +``` +(gdb) set args -fxx +``` + +Then, do: + +``` +(gdb) run +``` + +When something interesting happens, you can hit CTRL-C in the window, +and you should be back at the gdb prompt: + +``` +(gdb) +``` + +And follow the instructions in the next section. + +== Obtaining useful information + +Once you have a core dump loaded into gdb, or FreeRADIUS running under +gdb, you may use the commands below to get useful information about the +state of the server. + +If the server was built with threads, you can do: + +``` +(gdb) info threads +``` + +Which will give you information about the threads. If the server isn’t +threaded, that command-line will print a message saying so. + +Then, do: + +``` +(gdb) thread apply all bt full +``` + +If the server isn’t threaded, the `thread apply` section isn’t +necessary + +The output should be printed to the screen, and also sent to the +`gdb-radiusd.log` file. + +You should then submit the information from the log file, along with any +server output, the output of `radiusd -xv`, and information about your +operating system to: + +https://bugs.freeradius.org/ + +Submitting it to the bug database ensures that the bug report won’t get +forgotten, and that it will be dealt with in due course. + +You should provide the issue number in any mail sent to the user’s list. + +== Valgrind + +On Linux systems, `valgrind` is a useful tool that can catch certain +classes of bugs. To use it, run the server via: + +``` +$ valgrind --tool=memcheck --leak-check=full radiusd -Xm +``` + +It will print out certain kinds of errors to the screen. There may be a +number of errors related to OpenSSL, dlopen(), or libtldl. We cannot do +anything about those problems. However, any errors that are inside of +the FreeRADIUS source should be brought to our attention. + +== Running with `screen` + +If the bug is a crash of the server, and it takes a long time for the +crash to happen, perform the following steps: + +* Log in as root. +* Open a https://www.gnu.org/software/screen/[screen] session: `$ screen bash`. +* Make sure FreeRADIUS is not running. +* Make sure you have all the debug symbols about, or a debugable version +of the server installed (one built with `--enable-developer` as above). +* Configure screen to log to a file by pressing `Ctrl+a`, then `h`. +* Type `gdb /path/to/radiusd` (or /path/to/freeradius on Debian). +* At the `(gdb)` prompt, type `run -X`. +* Detach from screen with `Ctrl+a`, `d`. +* When you notice FreeRADIUS has died, reconnect to your screen session +`$ screen -D -r`. +* At the `(gdb)` prompt type `where` or for _lots_ of info try +`thread apply all bt full`. +* Tell screen to stop logging, `Ctrl+a`, `h`. +* Logout from screen. + +FreeRADIUS Project, copyright 2019 diff --git a/doc/antora/modules/developers/pages/coding-methods.adoc b/doc/antora/modules/developers/pages/coding-methods.adoc new file mode 100644 index 00000000000..3de92c460eb --- /dev/null +++ b/doc/antora/modules/developers/pages/coding-methods.adoc @@ -0,0 +1,235 @@ += Coding Methods + +The following is a short set of guidelines to follow while programming. It does +not address coding styles, function naming methods, or debugging methods. +Rather, it describes the processes which should go on in the programmer’s mind +while they are programming. + +Coding standards apply to function names, the look of the code, and coding +consistency. Coding methods apply to the daily practices used by the programmer +to write code. + +== Comment your code + +If you don’t, you’ll be forced to debug it six months later, when you have no clue +as to what it’s doing. + +If someone _really_ hates you, you’ll be forced to debug un-commented code that +someone else wrote. You don’t want to do that. + +For FreeRADIUS, use doxygen `@`-style comments so you get the +benefits of the developer documentation site, https://doc.freeradius.org/. + +== Give things reasonable names + +Variables and functions should have names. Calling them `x`, `xx`, +and `xxx` makes your life hell. Even `foo` and `i` are +problematic. + +Avoid smurfs. Don’t re-use struct names in field names, i. e. + +[source,c] +---- +struct smurf { + char *smurf_pappa_smurf; +} +---- + +If your code reads as full English sentences, you’re doing it right. + +== Check input parameters in the functions you write + +Your function _cannot_ do anything right if the user passed in garbage +and you were too lazy to check for garbage input. + +`assert()` (`fr_assert()`) is ugly. Use it. + +[NOTE] +==== +GIGO, "Garbage In, Garbage Out," is wrong. If your function gets +garbage input, it should complain loudly and with great +descriptiveness. +==== + +== Write useful error messages + +"Function failed" is useless as an error message. It makes debugging the code +impossible without source-level instrumentation. + +If you’re going to instrument the code at source level for error messages, leave +the error messages there, so the next sucker won’t have to do the same work all +over again. + +== Check error conditions from the functions you call + +Your function _cannot_ do anything right if you called another function, and +they gave you garbage output. + +One of the most common mistakes is: + +[source,c] +---- +fp = fopen(...); +fgetc(fp); /* core dumps! */ +---- + +If the programmer had bothered to check for a `NULL` fp (error +condition), then they could have produced a descriptive error message +instead of having the program core dump. + +== Core dumps are for weenies + +If your program core dumps accidentally, you’re a bad programmer. You don’t know +what your program is doing, or what it’s supposed to be doing when anything goes +wrong. + +If it hits an `assert()` and calls `abort()`, you’re a genius. You’ve thought +ahead to what _might_ go wrong, and put in an assertion to ensure that it fails +in a _known manner_ when something _does_ go wrong. (As it usually does…) + +== Initialize your variables + +`memset()` (`talloc_zero()`) is your friend. `ptr = NULL` is nice, +too. + +Having variables containing garbage values makes it easy for the code to do +garbage things. The contents of local variables are inputs to your function. See +xref:#_check_input_parameters_in_the_functions_you_write[#3]. + +It’s also nearly impossible for you to debug any problems, as you can’t tell the +variables with garbage values from the real ones. + +== Don’t allow buffer over-runs + +They’re usually accidental, but they cause core dumps. `strcpy()` and `strcat()` +are ugly. Use them under duress. + +`sizeof()` is your friend. + +== `const` is your friend + +If you don’t mean to modify an input structure to your function, declare it +`const`. Declare string constants `const`. It can’t hurt, and it allows more +errors to be found at compile time. + +Use `const` everywhere. Once you throw a few into your code, and have it save +you from stupid bugs, you’ll blindly throw in `const` everywhere. It’s a +life-saver. + +== Use C compiler warnings + +Turn on all of the C compiler warnings possible. You might have to turn some off +due to broken system header files, though. But the more warnings the merrier. + +Getting error messages at compile time is much preferable to getting core dumps +at run time. See xref:#_initialize_your_variables[#7]. + +Notice that the C compiler error messages are helpful? You should write error +messages like this, too. See xref:#_write_useful_error_messages[#4]. + +== Avoid UNIXisms and ASCIIisms and visualisms + +You don’t know under what system someone will try to run your code. Don’t demand +that others use the same OS or character set as you use. + +Never assign numbers to pointers. If foo is a `char*`, and you want it to be be +`NULL`, assign `NULL`, not `0`. The zeroth location is perfectly as addressable +as any other on plenty of OSes. Not all the world runs on Unix (though it should +:) ). + +Another common mistake is to assume that the zeroth character in the character +set is the string terminator. Instead of terminating a string with `0`, use +`'\0'`, which is always right. Similarly, `memset()` with the appropriate value: +`NULL`, `'\0'`, or `0` for pointers, chars, and numbers. + +Don’t put tabs in string constants, either. Always use `'\t'` to represent a +tab, instead of ASCII 9. Literal tabs are presented to readers of your code as +arbitrary whitespace, and it’s easy to mess up. + +== Make conditionals explicit + +Though it’s legal to test `if (foo) {}` if you test against the appropriate +value (like `NULL` or `'\0'`), your code is prettier and easier for others to +read without having to eyeball your prototypes continuously to figure out what +you’re doing (especially if your variables aren’t well-named). See +xref:#_give_things_reasonable_names[#2]. + +== Test your code + +Even Donald Knuth writes buggy code. You’ll never find all of the bugs in your +code. But writing a test program definitely helps. + +This means that you’ll have to write your code so that it will be easily +testable. As a result, it will look better and be easier to debug. + +== Hints, Tips, and Tricks + +This section lists many of the common `rules` associated with code submitted to +the project. There are always exceptions… but you must have a really good reason +for doing so. + +== Read the Documentation and follow the CodingStyle + +The FreeRADIUS server has a common coding style. Use real tabs to indent. There +is whitespace in variable assignments (`i = 1`, not `i=1`). + +When in doubt, format your code to look the same as code already in the server. +If your code deviates too much from the current style, it is likely to be +rejected without further review, and without comment. + +== #ifdefs are ugly + +Code cluttered with `#ifdef` s is difficult to read and maintain. Don’t do it. +Instead, put your `#ifdef` s in a header, and conditionally define `static +inline` functions, or macros, which are used in the code. Let the compiler +optimize away the 'no-op' case. + +Simple example, of poor code: + +[source,c] +---- +#ifdef CONFIG_MY_FUNKINESS + init_my_stuff(foo); +#endif +---- + +Cleaned-up example: + +(in header): + +[source,c] +---- +#ifndef CONFIG_MY_FUNKINESS + static inline void init_my_stuff(char *foo) {} +#endif +---- + +(in the code itself): + +[source,c] +---- +init_my_stuff(dev); +---- + +== `static inline` is better than a macro + +Static inline functions are greatly preferred over macros. They provide type +safety, have no length limitations, no formatting limitations, and under gcc +they are as cheap as macros. + +Macros should only be used for cases where a static inline is clearly suboptimal +(there a few, isolated cases of this in fast paths), or where it is impossible +to use a static inline function (such as string-izing). + +`static inline` is preferred over `$$static __inline__$$`, `extern inline`, and +`$$extern __inline__$$`. + +== Don’t over-design + +Don’t try to anticipate nebulous future cases which may or may not be useful: +_Make it as simple as you can, and no simpler._ + +Split up functionality as much as possible. If your code needs to do two +unrelated things, write two functions. Mashing two kinds of work into one +function makes the server difficult to debug and maintain. + diff --git a/doc/antora/modules/developers/pages/contributing.adoc b/doc/antora/modules/developers/pages/contributing.adoc new file mode 100644 index 00000000000..e4a4b0a1c5e --- /dev/null +++ b/doc/antora/modules/developers/pages/contributing.adoc @@ -0,0 +1,126 @@ += Contributing + +== Submitting patches or diff’s to the FreeRADIUS project + +For a person or company wishing to submit a change to the FreeRADIUS +project the process can sometimes be daunting if you’re not familiar +with "the system." This text is a collection of suggestions which can +greatly increase the chances of your change being accepted. + +Note: Only trivial patches will be accepted via email. Large patches, or +patches that modify a number of files MUST be submitted as a +https://github.com/FreeRADIUS/freeradius-server/pulls[pull-request via GitHub]. + +== Hints and tips + +=== 1. Describe your changes + +Describe the technical detail of the change(s) your patch or commit +includes. + +Be as specific as possible. The WORST descriptions possible include +things like "update file X", "bug fix for file X", or "this patch +includes updates for subsystem X. Please apply." + +If your description starts to get long, that’s a sign that you probably +need to split up your commit. See the next point. + +=== 2. Separate your changes + +Separate each logical change into its own commit. + +For example, if your changes include both bug fixes and performance +enhancements for a single module, separate those changes into two or +more patches. + +On the other hand, if you make a single change to numerous files, group +those changes into a single commit. Thus a single LOGICAL change is +contained within a single commit. + +If one commit depends on another commit in order for a change to be +complete, that is OK. Simply note "this commit depends on commit X" in +the extended commit description. + +If your commit includes significant whitespace changes these should also +be broken out into another, separate, commit. + +== Submitting patches via GitHub + +See the following links for more details about submitting via github: + +* https://help.github.com/articles/fork-a-repo +* http://wiki.freeradius.org/contributing/GitHub + +== Submitting patches via email + +=== 1. diff -u + +Use `diff -u` or `diff -urN` to create patches. + +All changes to the source occur in the form of patches, as generated by +diff(1). When creating your patch, make sure to create it in unified +diff format, as supplied by the `-u` argument to diff(1). Patches +should be based in the root source directory, not in any lower +subdirectory. + +To create a patch for a single file, it is often sufficient to do:: + +``` +SRCTREE=/home/user/src/freeradiusd/ +MYFILE=src/modules/rlm_foo/foo.c + +cd $SRCTREE +cp $MYFILE $MYFILE.orig +vi $MYFILE # make your change +diff -u $MYFILE.orig $MYFILE > /tmp/patch +``` + +To create a patch for multiple files, you should unpack a `vanilla`, +or unmodified source tree, and generate a diff against your own source +tree. For example: + +``` +MYSRC=/home/user/src/freeradiusd-feature/ + +gunzip freeradiusd-version.tar.gz +tar xvf freeradiusd-version.tar +diff -urN freeradiusd-version $MYSRC > ~/feature-version.patch +``` + +=== 2. Select e-mail destination + +If you are on the developers mailing list, send the patch there. +mailto:freeradius-devel@lists.freeradius.org[freeradius-devel@lists.freeradius.org] + +Otherwise, send the patch to +mailto:patches@freeradius.org[patches@freeradius.org] + +=== 3. No MIME, no links, no compression, no attachments. Just plain text + +The developers need to be able to read and comment on the changes you +are submitting. It is important for a developer to be able to `quote` +your changes, using standard e-mail tools, so that they may comment on +specific portions of your code. + +For this reason, all patches should be submitting e-mail `inline`. + +Do not attach the patch as a MIME attachment, compressed or not. Many +popular e-mail applications will not always transmit a MIME attachment +as plain text, making it impossible to comment on your code. A MIME +attachment also takes a bit more time to process, decreasing the +likelihood of your MIME-attached change being accepted. + +Compressed patches are generally rejected outright. If the developer has +to do additional work to read your patch, the odds are that it will be +ignored completely. + +=== 4. E-mail size + +Large changes are not appropriate for mailing lists, and some +maintainers. If your patch, exceeds 5Kb in size, you must submit the +patch via GitHub instead. + +=== 5. Name the version of the server + +It is important to note, either in the subject line or in the patch +description, the server version to which this patch applies. diff --git a/doc/antora/modules/developers/pages/coverage.adoc b/doc/antora/modules/developers/pages/coverage.adoc new file mode 100644 index 00000000000..af6048e39e7 --- /dev/null +++ b/doc/antora/modules/developers/pages/coverage.adoc @@ -0,0 +1,11 @@ += Code Coverage + +We use the link:https://gcc.gnu.org/onlinedocs/gcc/Gcov-Intro.html#Gcov-Intro[gcov] tool to know our tests coverage. + +[source,shell] +---- +$ make clean +$ make coverage +---- + +If completed with success, a pretty report will be available in `${source_tree}/build/coverage/index.html` diff --git a/doc/antora/modules/developers/pages/index.adoc b/doc/antora/modules/developers/pages/index.adoc new file mode 100644 index 00000000000..e66ef613829 --- /dev/null +++ b/doc/antora/modules/developers/pages/index.adoc @@ -0,0 +1,18 @@ += FreeRADIUS Development + +List with some usual howtos for FreeRADIUS. + +Programming reference documentation can be found at the +https://doc.freeradius.org/[Doxygen] site. + +== Topics + +* xref:bugs.adoc[Bugs] +* xref:coding-methods.adoc[Coding Methods] +* xref:coverage.adoc[Code Coverage] +* xref:profile.adoc[Profiling] +* xref:contributing.adoc[Contributing] +* xref:release-method.adoc[Release Method] + +Also see the xref:installation:dependencies.adoc[build +dependencies] page. diff --git a/doc/antora/modules/developers/pages/profile.adoc b/doc/antora/modules/developers/pages/profile.adoc new file mode 100644 index 00000000000..ca94f53a407 --- /dev/null +++ b/doc/antora/modules/developers/pages/profile.adoc @@ -0,0 +1,41 @@ += Profiling + +Build with gperftools, and ensure that it's built: + +[source,shell] +---- +$ grep profile Make.inc +GPERFTOOLS_LIBS = -lprofiler +---- + +Run your test using the profiling tools. One signal will start the +profiling, another will stop it. + +[source,shell] +---- +env CPUPROFILE=/tmp/freeradius.prof CPUPROFILESIGNAL=12 freeradius ... +killall -12 freeradius + ... wait ... +killall -12 freeradius +---- + +View the results + +[source,shell] +---- +pprof --text /path/to/freeradius /tmp/freeradius.prof +---- + +or as a graph + +[source,shell] +---- +pprof --gv /path/to/freeradius /tmp/freeradius.prof +---- + +or as cachgrind output + +[source,shell] +---- +pprof --cachegrind /path/to/freeradius /tmp/freeradius.prof +---- diff --git a/doc/antora/modules/developers/pages/release-method.adoc b/doc/antora/modules/developers/pages/release-method.adoc new file mode 100644 index 00000000000..1de9e2dc173 --- /dev/null +++ b/doc/antora/modules/developers/pages/release-method.adoc @@ -0,0 +1,55 @@ += Release Method + +== Topics + +[arabic] +. As of 2.0, the release process is much simpler. Edit the Changelog +with the version number and any last updates. + +``` +# vi doc/ChangeLog +# git commit doc/ChangeLog +``` + +[arabic, start=2] +. Change version numbers in the VERSION file: + +``` +# vi VERSION +# git commit VERSION +``` + +[arabic, start=3] +. Make the files + +NOTE: It also does `make dist-check`, which checks the build rules for +various packages. + +``` +# make dist +``` + +[arabic, start=4] +. Validate that the packages are OK. If so, tag the release. + +NOTE: This does NOT actually do the tagging! You will have to run the +command it prints out yourself. + +``` +# make dist-tag +``` + +[arabic, start=5] +. Sign the packages. You will need the correct GPG key for this to work. + +``` +# make dist-sign +``` + +[arabic, start=6] +. Push to the FTP site. You will need write access to the FTP site for +this to work. + +``` +# make dist-publish +```