Copyright ©2004, AXL Software™ & Michael Lecuyer, all rights reserved.
Fundamentals
Background
Operation
Authentication
Accounting
AuthorizationPractical
Examples: The Client, Session, Authentication, Authorization, Accounting
Authentication methods
Support
Background
TACACS+ is a protocol developed by Cisco™ to provide authentication, authorization, and accounting services to their own proprietary hardware with proprietary software. Authentication make sure the name and password are correct. Authorization is a means of providing provisioning of authorized resources, such as connection types and IP addresses. Accounting is just that, providing a means for tracking resources consumed.
There are two variants of the basic TACACS protocol: XTACACS and TACACS+ (a.k.a. TACACS Plus). This client works with TACACS+. It may work with some basic TACACS servers, but this is untested.
At some point a small effort was made to produce a 'Request for Comments' (RFC) which appeared as several drafts, the most modern is the
draft-grant-tacacs-02.txtdescribing TACACS+ version 1.78 and dating from January of1997. The document never made it to full RFC status.Operation
A TACACS+ client communicates to the server in conversations that are called
sessions. A session consists in almost all cases as a simple request and a reply. The server's TCP connection is opened for a session and closes when the reply packet is sent. The two packet types guaranteed to use this simple protocol are the Accounting and Authorization.Authentication normally follows the two-step transaction but in some cases it will require more steps. For example if either the name or password are missing from the request packet the server will send it's request for more information. A
continuepacket will be sent by the server andcontinuepacket will be sent by the client. For most purposes you will be sending complete request packets and continue packets will not be required. Not all servers support this extra banter properly and the specifications are clear that it is preferable to use the simplest possible conversation.Authentication
There are several combinations of authentication methods and augmentation types which are beyond the intended scope of this document. The most common form you'll find is the
LOGINauthentication type. This is where you pass login information (name and password) to the TACACS+ server and the person or thing (entity) is either authenticated or not. There are four supported types: PAP (plain text password), CHAP (challenge encoded password), MSCHAP (Microsoft™) CHAP, and ARAP (Apple™ login).Other types of authentication are change password (TAC_PLUS_AUTHEN_CHPASS - often supported), send password (TAC_PLUS_AUTHEN_SENDPASS - deprecated, discouraged, largely unsupported), and send authorization ( TAC_PLUS_AUTHEN_SENDAUTH). Send authorization means send the authorization credentials to the server so it can make a third party authentication on your behalf.
Accounting
Accounting requests are used to start, stop and since interim accounting information to the server. The accounting packets use 'attributes' to send this information. These attributes are text strings like 'paks=500' and inform the accounting logs about resource usage and who used them. There are lists of legal accounting attributes name in the draft-grant-tacacs-02.txt. Be sure to look at both the authorization and accounting attributes as they are all valid in accounting packets.
Authorization
Like accounting packets authorization uses attributes, although a more limited set. The attributes describe the requirements the client wishes bestowed. The server replies with attributes provisioning the client within the allowable policies configured on the server. Unlike accounting packet the server returns attributes in string form which the client will use to configure itself.
The Client
The client connects to the remote server on a particular port with perhaps a timeout value. The default timeout is generous, about ten seconds. This can be changed to other values. The 'secret' is the shared secret between the server and client. It should be difficult to guess and can be any length. This secret is used to encode the contents of the packet protecting the sensitive data from being exposed.
TACACSClient tc = new TACACSCLient(server, port, secret[, timeout]);TACACS+ offers us the notion of a 'session' which is partly for tracking information and partly for security. The session code, a four byte value, is used to help encode the packet differently each time. This is maintained internally and only of incidental knowledge. The session holds various common parameters used by all requests.
These are:
Common Parameters Name The entity name like 'michael'. Port This the name of a port, a string something like 'tty9'. Remote address This is a string representation of the remote address, a 'best effort' description of the location of the client. It might be an IP address or a physical location. It may be an outright falsehood and is not considered a reliable description in any case. Privilege level This is a numeric level ranging from 0 to 15 with the lowest number indicating the lowest level. The default level is 1 (TAC_PLUS_PRIV_LVL_USER). This is locally interpreted and there are no standard levels. // Get a session and set up the basic parameters. TACACSSession session = tc.createSession(null); session.setName("michael"); session.setPort("PC-AXL"); session.setRemoteAddress("AXL Software™"); session.setPrivLevel(TAC.TAC_PLUS_PRIV_LVL_USER);Now a simple example of plaintext authentication followed by authorization and finally accounting.
// Set up the authentication type of ASCII (plain text password) // and request PPP service. session.setAuthenType(TAC.TAC_PLUS_AUTHEN_TYPE_ASCII); session.setService(TAC.TAC_PLUS_AUTHEN_SVC_PPP); session.setData("test"); AuthenticationPacket authen =
(AuthenticationPacket) tc.authorization(TAC.TAC_PLUS_AUTHEN_METH_TACACSPLUS,session); if (authen.getStatus() != TAC.TAC_PLUS_AUTHEN_STATUS_PASS) throw new Exception("Failed to authenticate");// Create some authorization attributes. These aren't necessarily // reasonable attributes. AttributeList autha = new AttributeList(); autha.add("service=ppp"); autha.add("protocol=ip"); autha.add("addr=127.0.0.1"); session.setRequestAttributes(autha); // Perform the authorization. Claim we were authorized through TACACS+.
// An AuthorizationPacket will be returned. // Reset the client before the next exchange. tc.reset(); AuthorizationPacket author =
(AuthorizationPacket) tc.authorization(TAC.TAC_PLUS_AUTHEN_METH_TACACSPLUS,session);
// We can look for message from the server.
System.out.println("Client.accept: Server display message: " + author.getServerMessage());
System.out.println("Client.accept: Data: " + Util.toHexString(author.getData()));
System.out.println("Client.accept: Status is " + author.getStatus()); System.out.println("Response attributes: " + author.getResponseAttributes()); if (author.getStatus() == TAC.TAC_PLUS_AUTHOR_STATUS_FAIL) throw new Exception("Failed to get authorization."); // Try some accounting:
session.setAuthenType(TAC.TAC_PLUS_AUTHEN_TYPE_ASCII);
session.setService(TAC.TAC_PLUS_AUTHEN_SVC_NONE); // Create some accounting attributes. AttributeList accta = new AttributeList(); accta.add("paks=500"); accta.add("task_id=UniqueTaskId#300");
session.setRequestAttributes(accta); // Send the accounting start packet. tc.reset(); (AccountingPacket) ap = (AccountingPacket)tc.accounting(TAC.TAC_PLUS_ACCT_FLAG_START, session); if (ap.getStatus()!= TAC.TAC_PLUS_ACCT_STATUS_SUCCESS) throw new Exception("Failed to start accounting.");The above examples illustrate the basic operation of the client. Instead of re-using the original TACASSession a new one can be created by the TACACSClient. Using new sessions increases security as it changes the encoding for each session.
Authentication methods
There are four authentication method supported: PAP, CHAP, MSCHAP and ARAP. The first requires nothing special but setting the data value to the password:
session.setAuthenType(TAC.TAC_PLUS_AUTHEN_TYPE_PAP);
byte password[] = Util.toASCII("test");
tc.authentication(TAC.TAC_PLUS_AUTHEN_LOGIN, session, password);session.setAuthenType(TAC.TAC_PLUS_AUTHEN_TYPE_CHAP); data = AuthenticationPacket.createChap("test"); // Test for a pass status.session.setAuthenType(TAC.TAC_PLUS_AUTHEN_TYPE_MSCHAP); session.setService(TAC.TAC_PLUS_AUTHEN_SVC_NONE); data = new AuthenticationPacket().createMSCHAP(Util.toASCII("test")); // Test for a pass status.// ARAP is a mutual authentication system similar to MS-CHAP V2.
// The server authenticates the client and the client then
// authenticates the server's response.
session.setAuthenType(TAC.TAC_PLUS_AUTHEN_TYPE_ARAP); session.setService(TAC.TAC_PLUS_AUTHEN_SVC_NONE); AuthenticationPacket ap = new AuthenticationPacket(); data = ap.createARAP(Util.toASCII("test")); // Get the response challenge being sent to the server. byte arapChallenge[] = ap.getARAPChallenge(); // Authenticate. AuthenticationPacket ap; ap = (AuthenticationPacket) tc.authentication(TAC.TAC_PLUS_AUTHEN_LOGIN, session, data); // Verify that the server really is correct. if (ap.getStatus() == TAC.TAC_PLUS_AUTHEN_STATUS_PASS){ // Verify the response using the saved response challenge.
if (ap.verifyARAP(Util.toASCII("test"), arapChallenge) == true)
System.out.println("ARAP succeeded."); } else throw new Exception("ARAP authentication failed.");// This is an unlikely form of authentication. It results in the server // asking for more information, like a password, using a CONTINUE packet.
// It might be useful for an interactive client as it offers a prompt
// for the client to present to the terminal.
// // The data field is unused, which is why the server must ask for // more information. It would be better to use PAP authentication.
//
// At the time of this writing the TACACS+ server distributed by Cisco
// fails to return the CONTINUE packet although it properly
// constructs it. The version is F4.0.4.alpha.
session.setAuthenType(TAC.TAC_PLUS_AUTHEN_TYPE_ASCII);
session.setService(TAC.TAC_PLUS_AUTHEN_SVC_NONE); data = null; AuthenticationPacket ap; ap = (AuthenticationPacket) tc.authentication(TAC.TAC_PLUS_AUTHEN_LOGIN, session, data);
// To send a continue message with a password do this:
tc.reset()
byte password[] = Util.toASCII("test");
tc.authenticationContinue(TAC.TAC_PLUS_AUTHEN_TYPE_ASCII, session, null, password);Other authentication methods include using the TACACS+ server to perform authentication on behalf of the client which is beyond the scope of this document, but not beyond the scope of the client.
Character set
The character set the server uses is ASCII. Java uses UTF8 strings which usually, when converted to bytes usually results in US-ASCII as the default platform encoding. Explicit conversion of strings to bytes (and back) is recommended using the Util.toASCII() methods to convert strings and byte arrays. Use this when converting passwords and names from an outside source. The Util class is imported from com.theorem.tacacs.util.*.
The use of ASCII and not UTF-8 encoding limits the usefulness of TACACS in the real world.
Reply packet call backs
There is an alternate way to receive reply packets other than simply examining the return value of the accounting(), authorization() and authentication() methods. The results may be returned to any class implementing the TACACSCallback class. The TACACSClient.createSession()'s parameter is the instance of the class implementing the callback interface. You may, for example, use one callback for accounting and a different one for authentication.
Support for the AXL TACACS+ client is available at AXLRadius.com.
There are some good TACACS+ configuration and operation guides at the Cisco™ site. A freeware server is available at ftp://ftp-eng.cisco.com/pub/tacacs/. DES is not implemented but you can use OpenSSL to provide DES support. DES encryption is required for MSCHAP and ARAP.