blob: 9086846e788127446eb5383947a59fa48d8da71b [file] [log] [blame]
Ari Saha89831742015-06-26 10:31:48 -07001/*
Amit Ghoshc9ac1e52017-07-28 12:31:18 +01002 * Copyright 2017-present Open Networking Foundation
Ari Saha89831742015-06-26 10:31:48 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
Matteo Scandolocf847b82019-04-26 15:00:00 -070018package org.opencord.aaa.impl;
Ari Saha89831742015-06-26 10:31:48 -070019
Jonathan Hart4731dd92018-05-02 17:30:05 -070020import com.google.common.collect.Maps;
Ari Saha89831742015-06-26 10:31:48 -070021import org.onlab.packet.MacAddress;
22import org.onosproject.net.ConnectPoint;
Matteo Scandolocf847b82019-04-26 15:00:00 -070023import org.opencord.aaa.AuthenticationEvent;
24import org.opencord.aaa.StateMachineDelegate;
Ari Saha89831742015-06-26 10:31:48 -070025import org.slf4j.Logger;
Thomas Vachuskae9894202015-07-30 11:59:07 -070026
Jonathan Hart4731dd92018-05-02 17:30:05 -070027import java.util.Map;
Ari Saha89831742015-06-26 10:31:48 -070028
29import static org.slf4j.LoggerFactory.getLogger;
30
31/**
32 * AAA Finite State Machine.
33 */
34
Carmelo Cascone58b53292019-09-30 12:35:31 -070035public class StateMachine {
Ari Saha89831742015-06-26 10:31:48 -070036 //INDEX to identify the state in the transition table
37 static final int STATE_IDLE = 0;
38 static final int STATE_STARTED = 1;
39 static final int STATE_PENDING = 2;
40 static final int STATE_AUTHORIZED = 3;
41 static final int STATE_UNAUTHORIZED = 4;
42
43 //INDEX to identify the transition in the transition table
44 static final int TRANSITION_START = 0; // --> started
45 static final int TRANSITION_REQUEST_ACCESS = 1;
46 static final int TRANSITION_AUTHORIZE_ACCESS = 2;
47 static final int TRANSITION_DENY_ACCESS = 3;
48 static final int TRANSITION_LOGOFF = 4;
49
Amit Ghoshc9ac1e52017-07-28 12:31:18 +010050 private static int identifier = -1;
Ari Saha89831742015-06-26 10:31:48 -070051 private byte challengeIdentifier;
52 private byte[] challengeState;
53 private byte[] username;
54 private byte[] requestAuthenticator;
55
56 // Supplicant connectivity info
Ray Milkeyf61a24e2015-09-24 16:34:02 -070057 private ConnectPoint supplicantConnectpoint;
58 private MacAddress supplicantAddress;
59 private short vlanId;
Amit Ghoshc9ac1e52017-07-28 12:31:18 +010060 private byte priorityCode;
Ari Saha89831742015-06-26 10:31:48 -070061
62 private String sessionId = null;
63
64 private final Logger log = getLogger(getClass());
65
Ari Saha89831742015-06-26 10:31:48 -070066 private State[] states = {
67 new Idle(), new Started(), new Pending(), new Authorized(), new Unauthorized()
68 };
69
70
71 //State transition table
72 /*
73
74 state IDLE | STARTED | PENDING | AUTHORIZED | UNAUTHORIZED
75 ////
76 input
77 ----------------------------------------------------------------------------------------------------
78
ke han04e47f32016-10-28 14:15:43 +080079 START STARTED | _ | _ | STARTED | STARTED
Ari Saha89831742015-06-26 10:31:48 -070080
81 REQUEST_ACCESS _ | PENDING | _ | _ | _
82
83 AUTHORIZE_ACCESS _ | _ | AUTHORIZED | _ | _
84
85 DENY_ACCESS _ | - | UNAUTHORIZED | _ | _
86
87 LOGOFF _ | _ | _ | IDLE | IDLE
88 */
89
90 private int[] idleTransition =
91 {STATE_STARTED, STATE_IDLE, STATE_IDLE, STATE_IDLE, STATE_IDLE};
92 private int[] startedTransition =
93 {STATE_STARTED, STATE_PENDING, STATE_STARTED, STATE_STARTED, STATE_STARTED};
94 private int[] pendingTransition =
95 {STATE_PENDING, STATE_PENDING, STATE_AUTHORIZED, STATE_UNAUTHORIZED, STATE_PENDING};
96 private int[] authorizedTransition =
Qianqian Hu0c349812016-02-15 17:25:22 +080097 {STATE_STARTED, STATE_AUTHORIZED, STATE_AUTHORIZED, STATE_AUTHORIZED, STATE_IDLE};
Ari Saha89831742015-06-26 10:31:48 -070098 private int[] unauthorizedTransition =
ke han04e47f32016-10-28 14:15:43 +080099 {STATE_STARTED, STATE_UNAUTHORIZED, STATE_UNAUTHORIZED, STATE_UNAUTHORIZED, STATE_IDLE};
Ari Saha89831742015-06-26 10:31:48 -0700100
101 //THE TRANSITION TABLE
102 private int[][] transition =
103 {idleTransition, startedTransition, pendingTransition, authorizedTransition,
104 unauthorizedTransition};
105
106 private int currentState = STATE_IDLE;
107
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700108 // Maps of state machines. Each state machine is represented by an
109 // unique identifier on the switch: dpid + port number
110 private static Map<String, StateMachine> sessionIdMap;
111 private static Map<Integer, StateMachine> identifierMap;
Ari Saha89831742015-06-26 10:31:48 -0700112
Jonathan Hart5db44532018-07-12 18:13:54 -0700113 private static StateMachineDelegate delegate;
114
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700115 public static void initializeMaps() {
116 sessionIdMap = Maps.newConcurrentMap();
117 identifierMap = Maps.newConcurrentMap();
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100118 identifier = -1;
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700119 }
120
121 public static void destroyMaps() {
122 sessionIdMap = null;
123 identifierMap = null;
124 }
125
Matteo Scandolocf847b82019-04-26 15:00:00 -0700126 public static void setDelegate(StateMachineDelegate delegate) {
127 StateMachine.delegate = delegate;
Jonathan Hart5db44532018-07-12 18:13:54 -0700128 }
129
130 public static void unsetDelegate(StateMachineDelegate delegate) {
131 if (StateMachine.delegate == delegate) {
132 StateMachine.delegate = null;
133 }
134 }
135
Qianqian Hu61a6a402016-02-16 15:18:05 +0800136 public static Map<String, StateMachine> sessionIdMap() {
137 return sessionIdMap;
138 }
139
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700140 public static StateMachine lookupStateMachineById(byte identifier) {
141 return identifierMap.get((int) identifier);
142 }
143
144 public static StateMachine lookupStateMachineBySessionId(String sessionId) {
145 return sessionIdMap.get(sessionId);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100146 }
147
148 public static void deleteStateMachineMapping(StateMachine machine) {
149 identifierMap.entrySet().removeIf(e -> e.getValue().equals(machine));
150 }
151
152 /**
David K. Bainbridge62019492017-07-28 17:02:10 -0700153 * Deletes authentication state machine records for a given MAC address.
154 * @param mac mac address of the suppliant who's state machine should be removed
155 */
156 public static void deleteByMac(MacAddress mac) {
157
158 // Walk the map from session IDs to state machines looking for a MAC match
159 for (Map.Entry<String, StateMachine> e : sessionIdMap.entrySet()) {
160
161 // If a MAC match is found then delete the entry from the session ID
162 // and identifier map as well as call delete identifier to clean up
163 // the identifier bit set.
164 if (e.getValue() != null && e.getValue().supplicantAddress != null &&
165 e.getValue().supplicantAddress.equals(mac)) {
166 sessionIdMap.remove(e.getValue().sessionId);
167 if (e.getValue().identifier != -1) {
168 deleteStateMachineMapping(e.getValue());
169 }
170 break;
171 }
172 }
173 }
174
175 /**
Jonathan Hart932bedc2018-07-12 13:46:09 -0700176 * Creates a new StateMachine with the given session ID.
Thomas Vachuskae9894202015-07-30 11:59:07 -0700177 *
Jonathan Hart932bedc2018-07-12 13:46:09 -0700178 * @param sessionId session Id represented by the switch dpid + port number
Ari Saha89831742015-06-26 10:31:48 -0700179 */
Jonathan Hart932bedc2018-07-12 13:46:09 -0700180 public StateMachine(String sessionId) {
181 log.info("Creating a new state machine for {}", sessionId);
Ari Saha89831742015-06-26 10:31:48 -0700182 this.sessionId = sessionId;
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700183 sessionIdMap.put(sessionId, this);
Ari Saha89831742015-06-26 10:31:48 -0700184 }
185
186 /**
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700187 * Gets the connect point for the supplicant side.
188 *
189 * @return supplicant connect point
190 */
191 public ConnectPoint supplicantConnectpoint() {
192 return supplicantConnectpoint;
193 }
194
195 /**
196 * Sets the supplicant side connect point.
197 *
198 * @param supplicantConnectpoint supplicant select point.
199 */
200 public void setSupplicantConnectpoint(ConnectPoint supplicantConnectpoint) {
201 this.supplicantConnectpoint = supplicantConnectpoint;
202 }
203
204 /**
205 * Gets the MAC address of the supplicant.
206 *
207 * @return supplicant MAC address
208 */
209 public MacAddress supplicantAddress() {
210 return supplicantAddress;
211 }
212
213 /**
214 * Sets the supplicant MAC address.
215 *
216 * @param supplicantAddress new supplicant MAC address
217 */
218 public void setSupplicantAddress(MacAddress supplicantAddress) {
219 this.supplicantAddress = supplicantAddress;
220 }
221
222 /**
223 * Gets the client's Vlan ID.
224 *
225 * @return client vlan ID
226 */
227 public short vlanId() {
228 return vlanId;
229 }
230
231 /**
232 * Sets the client's vlan ID.
233 *
234 * @param vlanId new client vlan ID
235 */
236 public void setVlanId(short vlanId) {
237 this.vlanId = vlanId;
238 }
239
240 /**
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100241 * Gets the client's priority Code.
242 *
243 * @return client Priority code
244 */
245 public byte priorityCode() {
246 return priorityCode;
247 }
248
249 /**
250 * Sets the client's priority Code.
251 *
252 * @param priorityCode new client priority Code
253 */
254 public void setPriorityCode(byte priorityCode) {
255 this.priorityCode = priorityCode;
256 }
257
258 /**
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700259 * Gets the client id that is requesting for access.
Thomas Vachuskae9894202015-07-30 11:59:07 -0700260 *
Ari Saha89831742015-06-26 10:31:48 -0700261 * @return The client id.
262 */
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700263 public String sessionId() {
Ari Saha89831742015-06-26 10:31:48 -0700264 return this.sessionId;
265 }
266
267 /**
Ari Saha89831742015-06-26 10:31:48 -0700268 * Set the challenge identifier and the state issued by the RADIUS.
Thomas Vachuskae9894202015-07-30 11:59:07 -0700269 *
Ari Saha89831742015-06-26 10:31:48 -0700270 * @param challengeIdentifier The challenge identifier set into the EAP packet from the RADIUS message.
Thomas Vachuskae9894202015-07-30 11:59:07 -0700271 * @param challengeState The challenge state from the RADIUS.
Ari Saha89831742015-06-26 10:31:48 -0700272 */
273 protected void setChallengeInfo(byte challengeIdentifier, byte[] challengeState) {
274 this.challengeIdentifier = challengeIdentifier;
275 this.challengeState = challengeState;
276 }
Thomas Vachuskae9894202015-07-30 11:59:07 -0700277
Ari Saha89831742015-06-26 10:31:48 -0700278 /**
279 * Set the challenge identifier issued by the RADIUS on the access challenge request.
Thomas Vachuskae9894202015-07-30 11:59:07 -0700280 *
Ari Saha89831742015-06-26 10:31:48 -0700281 * @param challengeIdentifier The challenge identifier set into the EAP packet from the RADIUS message.
282 */
283 protected void setChallengeIdentifier(byte challengeIdentifier) {
284 log.info("Set Challenge Identifier to {}", challengeIdentifier);
285 this.challengeIdentifier = challengeIdentifier;
286 }
287
288 /**
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700289 * Gets the challenge EAP identifier set by the RADIUS.
Thomas Vachuskae9894202015-07-30 11:59:07 -0700290 *
Ari Saha89831742015-06-26 10:31:48 -0700291 * @return The challenge EAP identifier.
292 */
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700293 protected byte challengeIdentifier() {
Ari Saha89831742015-06-26 10:31:48 -0700294 return this.challengeIdentifier;
295 }
296
297
298 /**
299 * Set the challenge state info issued by the RADIUS.
Thomas Vachuskae9894202015-07-30 11:59:07 -0700300 *
Ari Saha89831742015-06-26 10:31:48 -0700301 * @param challengeState The challenge state from the RADIUS.
302 */
303 protected void setChallengeState(byte[] challengeState) {
304 log.info("Set Challenge State");
305 this.challengeState = challengeState;
306 }
307
308 /**
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700309 * Gets the challenge state set by the RADIUS.
Thomas Vachuskae9894202015-07-30 11:59:07 -0700310 *
Ari Saha89831742015-06-26 10:31:48 -0700311 * @return The challenge state.
312 */
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700313 protected byte[] challengeState() {
Ari Saha89831742015-06-26 10:31:48 -0700314 return this.challengeState;
315 }
316
317 /**
318 * Set the username.
Thomas Vachuskae9894202015-07-30 11:59:07 -0700319 *
Ari Saha89831742015-06-26 10:31:48 -0700320 * @param username The username sent to the RADIUS upon access request.
321 */
322 protected void setUsername(byte[] username) {
323 this.username = username;
324 }
325
Ari Saha89831742015-06-26 10:31:48 -0700326 /**
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700327 * Gets the username.
Thomas Vachuskae9894202015-07-30 11:59:07 -0700328 *
Ari Saha89831742015-06-26 10:31:48 -0700329 * @return The requestAuthenticator.
330 */
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700331 protected byte[] requestAuthenticator() {
Ari Saha89831742015-06-26 10:31:48 -0700332 return this.requestAuthenticator;
333 }
334
335 /**
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700336 * Sets the authenticator.
Thomas Vachuskae9894202015-07-30 11:59:07 -0700337 *
Ari Saha89831742015-06-26 10:31:48 -0700338 * @param authenticator The username sent to the RADIUS upon access request.
339 */
340 protected void setRequestAuthenticator(byte[] authenticator) {
341 this.requestAuthenticator = authenticator;
342 }
343
344
345 /**
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700346 * Gets the username.
Thomas Vachuskae9894202015-07-30 11:59:07 -0700347 *
Ari Saha89831742015-06-26 10:31:48 -0700348 * @return The username.
349 */
Carmelo Cascone58b53292019-09-30 12:35:31 -0700350 public byte[] username() {
Ari Saha89831742015-06-26 10:31:48 -0700351 return this.username;
352 }
353
354 /**
355 * Return the identifier of the state machine.
Thomas Vachuskae9894202015-07-30 11:59:07 -0700356 *
Ari Saha89831742015-06-26 10:31:48 -0700357 * @return The state machine identifier.
358 */
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100359 public synchronized byte identifier() {
360 identifier = (identifier + 1) % 255;
361 identifierMap.put(identifier, this);
362 return (byte) identifier;
Ari Saha89831742015-06-26 10:31:48 -0700363 }
364
Ari Saha89831742015-06-26 10:31:48 -0700365 /**
366 * Move to the next state.
Thomas Vachuskae9894202015-07-30 11:59:07 -0700367 *
Ray Milkey78e95a42015-09-24 08:36:45 -0700368 * @param msg message
Ari Saha89831742015-06-26 10:31:48 -0700369 */
Thomas Vachuskae9894202015-07-30 11:59:07 -0700370 private void next(int msg) {
Ari Saha89831742015-06-26 10:31:48 -0700371 currentState = transition[currentState][msg];
372 log.info("Current State " + currentState);
373 }
374
375 /**
376 * Client has requested the start action to allow network access.
Thomas Vachuskae9894202015-07-30 11:59:07 -0700377 *
378 * @throws StateMachineException if authentication protocol is violated
Ari Saha89831742015-06-26 10:31:48 -0700379 */
380 public void start() throws StateMachineException {
Ray Milkey78e95a42015-09-24 08:36:45 -0700381 states[currentState].start();
Jonathan Hart5db44532018-07-12 18:13:54 -0700382
383 delegate.notify(new AuthenticationEvent(
384 AuthenticationEvent.Type.STARTED, supplicantConnectpoint));
385
Ray Milkey78e95a42015-09-24 08:36:45 -0700386 //move to the next state
387 next(TRANSITION_START);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100388 identifier = this.identifier();
Ari Saha89831742015-06-26 10:31:48 -0700389 }
390
391 /**
392 * An Identification information has been sent by the supplicant.
393 * Move to the next state if possible.
Thomas Vachuskae9894202015-07-30 11:59:07 -0700394 *
395 * @throws StateMachineException if authentication protocol is violated
Ari Saha89831742015-06-26 10:31:48 -0700396 */
397 public void requestAccess() throws StateMachineException {
Ray Milkey78e95a42015-09-24 08:36:45 -0700398 states[currentState].requestAccess();
Jonathan Hart5db44532018-07-12 18:13:54 -0700399
400 delegate.notify(new AuthenticationEvent(
401 AuthenticationEvent.Type.REQUESTED, supplicantConnectpoint));
402
Ray Milkey78e95a42015-09-24 08:36:45 -0700403 //move to the next state
404 next(TRANSITION_REQUEST_ACCESS);
Ari Saha89831742015-06-26 10:31:48 -0700405 }
406
407 /**
408 * RADIUS has accepted the identification.
409 * Move to the next state if possible.
Thomas Vachuskae9894202015-07-30 11:59:07 -0700410 *
411 * @throws StateMachineException if authentication protocol is violated
Ari Saha89831742015-06-26 10:31:48 -0700412 */
413 public void authorizeAccess() throws StateMachineException {
Ray Milkey78e95a42015-09-24 08:36:45 -0700414 states[currentState].radiusAccepted();
415 //move to the next state
416 next(TRANSITION_AUTHORIZE_ACCESS);
Ari Saha89831742015-06-26 10:31:48 -0700417
Jonathan Hart5db44532018-07-12 18:13:54 -0700418 delegate.notify(new AuthenticationEvent(
419 AuthenticationEvent.Type.APPROVED, supplicantConnectpoint));
Ari Saha89831742015-06-26 10:31:48 -0700420
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100421 // Clear mapping
422 deleteStateMachineMapping(this);
Ari Saha89831742015-06-26 10:31:48 -0700423 }
424
425 /**
426 * RADIUS has denied the identification.
427 * Move to the next state if possible.
Thomas Vachuskae9894202015-07-30 11:59:07 -0700428 *
429 * @throws StateMachineException if authentication protocol is violated
Ari Saha89831742015-06-26 10:31:48 -0700430 */
431 public void denyAccess() throws StateMachineException {
Ray Milkey78e95a42015-09-24 08:36:45 -0700432 states[currentState].radiusDenied();
433 //move to the next state
434 next(TRANSITION_DENY_ACCESS);
Jonathan Hart5db44532018-07-12 18:13:54 -0700435
436 delegate.notify(new AuthenticationEvent(
437 AuthenticationEvent.Type.DENIED, supplicantConnectpoint));
438
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100439 // Clear mappings
440 deleteStateMachineMapping(this);
Ari Saha89831742015-06-26 10:31:48 -0700441 }
442
443 /**
444 * Logoff request has been requested.
445 * Move to the next state if possible.
Thomas Vachuskae9894202015-07-30 11:59:07 -0700446 *
447 * @throws StateMachineException if authentication protocol is violated
Ari Saha89831742015-06-26 10:31:48 -0700448 */
449 public void logoff() throws StateMachineException {
Ray Milkey78e95a42015-09-24 08:36:45 -0700450 states[currentState].logoff();
451 //move to the next state
452 next(TRANSITION_LOGOFF);
Ari Saha89831742015-06-26 10:31:48 -0700453 }
454
455 /**
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700456 * Gets the current state.
Thomas Vachuskae9894202015-07-30 11:59:07 -0700457 *
Ari Saha89831742015-06-26 10:31:48 -0700458 * @return The current state. Could be STATE_IDLE, STATE_STARTED, STATE_PENDING, STATE_AUTHORIZED,
459 * STATE_UNAUTHORIZED.
460 */
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700461 public int state() {
Ari Saha89831742015-06-26 10:31:48 -0700462 return currentState;
463 }
464
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700465 @Override
Ari Saha89831742015-06-26 10:31:48 -0700466 public String toString() {
467 return ("sessionId: " + this.sessionId) + "\t" + ("identifier: " + this.identifier) + "\t" +
468 ("state: " + this.currentState);
469 }
Ari Saha89831742015-06-26 10:31:48 -0700470
Ray Milkey78e95a42015-09-24 08:36:45 -0700471 abstract class State {
472 private final Logger log = getLogger(getClass());
Thomas Vachuskae9894202015-07-30 11:59:07 -0700473
Ray Milkey78e95a42015-09-24 08:36:45 -0700474 private String name = "State";
Ari Saha89831742015-06-26 10:31:48 -0700475
Ray Milkey78e95a42015-09-24 08:36:45 -0700476 public void start() throws StateMachineInvalidTransitionException {
477 log.warn("START transition from this state is not allowed.");
478 }
Ari Saha89831742015-06-26 10:31:48 -0700479
Ray Milkey78e95a42015-09-24 08:36:45 -0700480 public void requestAccess() throws StateMachineInvalidTransitionException {
481 log.warn("REQUEST ACCESS transition from this state is not allowed.");
482 }
483
484 public void radiusAccepted() throws StateMachineInvalidTransitionException {
485 log.warn("AUTHORIZE ACCESS transition from this state is not allowed.");
486 }
487
488 public void radiusDenied() throws StateMachineInvalidTransitionException {
489 log.warn("DENY ACCESS transition from this state is not allowed.");
490 }
491
492 public void logoff() throws StateMachineInvalidTransitionException {
493 log.warn("LOGOFF transition from this state is not allowed.");
494 }
Ari Saha89831742015-06-26 10:31:48 -0700495 }
Thomas Vachuskae9894202015-07-30 11:59:07 -0700496
Ray Milkey78e95a42015-09-24 08:36:45 -0700497 /**
498 * Idle state: supplicant is logged of from the network.
499 */
500 class Idle extends State {
501 private final Logger log = getLogger(getClass());
502 private String name = "IDLE_STATE";
503
504 public void start() {
505 log.info("Moving from IDLE state to STARTED state.");
506 }
Ari Saha89831742015-06-26 10:31:48 -0700507 }
Thomas Vachuskae9894202015-07-30 11:59:07 -0700508
Ray Milkey78e95a42015-09-24 08:36:45 -0700509 /**
510 * Started state: supplicant has entered the network and informed the authenticator.
511 */
512 class Started extends State {
513 private final Logger log = getLogger(getClass());
514 private String name = "STARTED_STATE";
515
516 public void requestAccess() {
517 log.info("Moving from STARTED state to PENDING state.");
518 }
Ari Saha89831742015-06-26 10:31:48 -0700519 }
Thomas Vachuskae9894202015-07-30 11:59:07 -0700520
Ray Milkey78e95a42015-09-24 08:36:45 -0700521 /**
522 * Pending state: supplicant has been identified by the authenticator but has not access yet.
523 */
524 class Pending extends State {
525 private final Logger log = getLogger(getClass());
526 private String name = "PENDING_STATE";
527
528 public void radiusAccepted() {
529 log.info("Moving from PENDING state to AUTHORIZED state.");
530 }
531
532 public void radiusDenied() {
533 log.info("Moving from PENDING state to UNAUTHORIZED state.");
534 }
Ari Saha89831742015-06-26 10:31:48 -0700535 }
Thomas Vachuskae9894202015-07-30 11:59:07 -0700536
Ray Milkey78e95a42015-09-24 08:36:45 -0700537 /**
538 * Authorized state: supplicant port has been accepted, access is granted.
539 */
540 class Authorized extends State {
541 private final Logger log = getLogger(getClass());
542 private String name = "AUTHORIZED_STATE";
Ari Saha89831742015-06-26 10:31:48 -0700543
Qianqian Hu0c349812016-02-15 17:25:22 +0800544 public void start() {
545 log.info("Moving from AUTHORIZED state to STARTED state.");
546 }
547
Ray Milkey78e95a42015-09-24 08:36:45 -0700548 public void logoff() {
Ari Saha89831742015-06-26 10:31:48 -0700549
Ray Milkey78e95a42015-09-24 08:36:45 -0700550 log.info("Moving from AUTHORIZED state to IDLE state.");
551 }
Ari Saha89831742015-06-26 10:31:48 -0700552 }
553
Ray Milkey78e95a42015-09-24 08:36:45 -0700554 /**
555 * Unauthorized state: supplicant port has been rejected, access is denied.
556 */
557 class Unauthorized extends State {
558 private final Logger log = getLogger(getClass());
559 private String name = "UNAUTHORIZED_STATE";
560
ke han04e47f32016-10-28 14:15:43 +0800561 public void start() {
562 log.info("Moving from UNAUTHORIZED state to STARTED state.");
563 }
564
Ray Milkey78e95a42015-09-24 08:36:45 -0700565 public void logoff() {
566 log.info("Moving from UNAUTHORIZED state to IDLE state.");
567 }
Ari Saha89831742015-06-26 10:31:48 -0700568 }
Ari Saha89831742015-06-26 10:31:48 -0700569
570
Ari Saha89831742015-06-26 10:31:48 -0700571}