Store username in Session.
[dftpd.git] / Session.cpp
blob928d94c48ffb03b7871d746603193893887c7f89
1 #include <iostream>
2 #include <string.h>
3 #include <errno.h>
4 #include <fcntl.h>
5 #include "Session.hpp"
6 #include "SessionController.hpp"
7 #include "String.hpp"
8 #include "Exceptions.hpp"
10 int Session::m_counter = 0;
12 Session::Session( int controlSock, const SessionControllerPtr& sessionController, const AuthPtr& auth )
13 : m_control( new Telnet( controlSock ) )
14 , m_controlSock( controlSock )
15 , m_id( m_counter++ )
16 , m_state( S_GREETING )
17 , m_sessionController( sessionController )
18 , m_auth( auth )
20 std::cout << "[Session] Initializing session " << m_id << std::endl;
22 // Set socket to non-blocking
23 if( fcntl( m_controlSock, F_SETFL, O_NONBLOCK ) == -1 )
25 throw strerror( errno );
29 Session::~Session()
31 if( m_controlSock != 0 )
33 std::cout << "[Session] Closing control socket " << m_id << std::endl;
34 close( m_controlSock );
38 SessionPtr Session::Create( int controlSock, const SessionControllerPtr& sessionController, const AuthPtr& auth )
40 SessionPtr ret( new Session( controlSock, sessionController, auth ) );
41 ret->m_this = ret;
43 return ret;
46 void Session::Tick()
48 try
50 try
52 switch( m_state )
54 case S_GREETING:
55 SendGreeting();
56 m_state = S_LOGIN;
57 break;
59 case S_LOGIN:
60 if( AwaitLogin() )
62 m_state = S_PASSWORD;
64 break;
66 case S_PASSWORD:
68 PassState state = AwaitPassword();
70 if( state == PS_LOGGEDIN )
72 m_state = S_READY;
74 else if( state == PS_BADPASS )
76 m_state = S_LOGIN;
78 break;
81 case S_READY:
82 AwaitReady();
83 break;
85 default:
86 break;
89 catch( SyntaxError& e )
91 SendSyntaxError();
93 catch( QuitRequested& e )
95 m_control->Write( "221 Bye" );
96 Remove();
99 catch( ConnectionTerminated& e )
101 std::cout << "[Session] Connection " << m_id << " terminated\n";
102 Remove();
106 void Session::Remove()
108 SessionControllerPtr sessionController = m_sessionController.lock();
110 if( !sessionController )
112 throw "Session lost SessionController";
115 sessionController->Remove( m_this.lock() );
118 void Session::SendGreeting()
120 m_control->Write( "220 Dumb FTP Server ready" );
123 void Session::SendSyntaxError()
125 m_control->Write( "500 Syntax error" );
128 void Session::SendNotLoggedIn()
130 m_control->Write( "530 Not logged in" );
133 bool Session::AwaitLogin()
135 if( m_control->Read() )
137 Command cmd = GetCommand();
139 if( cmd[0] == "USER" )
141 if( cmd.size() != 2 )
143 SendSyntaxError();
144 return false;
147 if( m_auth->Login( cmd[1] ) )
149 m_control->Write( "331 Need password" );
150 m_user = cmd[1];
151 return true;
153 else
155 SendNotLoggedIn();
156 return false;
159 else if( cmd[0] == "QUIT" )
161 throw QuitRequestedException;
163 else
165 SendNotLoggedIn();
169 return false;
172 Session::PassState Session::AwaitPassword()
174 if( m_control->Read() )
176 Command cmd = GetCommand();
178 if( cmd[0] == "PASS" )
180 if( cmd.size() != 2 )
182 SendSyntaxError();
183 return PS_BADPASS;
186 if( m_auth->Password( cmd[1] ) )
188 m_control->Write( "230 Logged in" );
189 return PS_LOGGEDIN;
191 else
193 SendNotLoggedIn();
194 return PS_BADPASS;
197 else if( cmd[0] == "QUIT" )
199 throw QuitRequestedException;
201 else
203 SendNotLoggedIn();
204 return PS_BADPASS;
208 return PS_NONE;
211 void Session::AwaitReady()
213 if( m_control->Read() )
215 Command cmd = GetCommand();
217 if( cmd[0] == "QUIT" )
219 throw QuitRequestedException;
221 else if( cmd[0] == "NOOP" )
223 m_control->Write( "200 OK" );
225 else if( cmd[0] == "MODE" )
227 HandleMode( cmd );
229 else if( cmd[0] == "TYPE" )
231 HandleType( cmd );
233 else if( cmd[0] == "STRU" )
235 HandleStru( cmd );
237 else
239 throw SyntaxErrorException;
244 void Session::HandleMode( const Command& cmd )
246 if( cmd.size() != 2 )
248 throw SyntaxErrorException;
251 std::string param = cmd[1];
252 ToUpper( param );
254 if( param == "S" )
256 m_control->Write( "200 OK" );
258 else if( param == "B" || param == "C" )
260 m_control->Write( "504 Not implemented" );
262 else
264 throw SyntaxErrorException;
268 void Session::HandleType( const Command& cmd )
270 if( cmd.size() < 2 || cmd.size() > 3)
272 throw SyntaxErrorException;
275 std::string param = cmd[1];
276 ToUpper( param );
278 if( param == "A" )
280 if( cmd.size() == 3 )
282 std::string param2 = cmd[2];
283 ToUpper( param2 );
285 if( param2 != "N" )
287 m_control->Write( "504 Not implemented" );
288 return;
292 m_control->Write( "200 OK" );
294 else if( param == "E" || param == "I" || param == "L" )
296 m_control->Write( "504 Not implemented" );
298 else
300 throw SyntaxErrorException;
304 void Session::HandleStru( const Command& cmd )
306 if( cmd.size() != 2 )
308 throw SyntaxErrorException;
311 std::string param = cmd[1];
312 ToUpper( param );
314 if( param == "F" )
316 m_control->Write( "200 OK" );
318 else if( param == "R" )
320 throw "STRU R not implemented";
322 else if( param == "P" )
324 m_control->Write( "504 Not implemented" );
326 else
328 throw SyntaxErrorException;