Merge branch 'next' of ssh://down.oryx.com/oryx/aox into next
[aox:aox.git] / sasl / saslconnection.cpp
1 // Copyright 2009 The Archiveopteryx Developers <info@aox.org>
2
3 #include "saslconnection.h"
4
5 #include "user.h"
6 #include "query.h"
7 #include "estring.h"
8 #include "endpoint.h"
9 #include "eventloop.h"
10
11 // time
12 #include <time.h>
13
14
15 /*! \class SaslConnection saslconnection.h
16     A connection that can engage in a SASL negotiation.
17 */
18
19 /*! Creates an Inactive \a type connection using \a fd. */
20
21 SaslConnection::SaslConnection( int fd, Type type )
22     : Connection( fd, type )
23 {
24 }
25
26
27 /*! Obligatory virtual destructor. */
28
29 SaslConnection::~SaslConnection()
30 {
31 }
32
33
34 /*! \fn virtual void SaslConnection::sendChallenge( const EString & s ) = 0
35
36     This virtual function must be defined by SaslConnection subclasses.
37     It is called by a SaslMechanism to send the challenge \a s, and is
38     responsible for enqueue()ing a correctly-encoded version of it.
39 */
40
41
42 /*! Returns a pointer to the authenticated User for this Connection, or
43     0 if a user has not yet been authenticated.
44 */
45
46 User * SaslConnection::user() const
47 {
48     return u;
49 }
50
51
52 /*! Informs this Connection that \a user has been authenticated using
53     the named \a mechanism. After a call to this function, user() will
54     return the specified \a user.
55 */
56
57 void SaslConnection::setUser( User * user, const EString & mechanism )
58 {
59     u = user;
60     m = mechanism;
61     s = (uint)time(0);
62 }
63
64
65 /*! This reimplementation logs the connection in the connections table
66     and cancels any other queries still running.
67
68     If the connection is closed as part of server shutdown, then it's
69     probably too late to execute a new Query. We're tolerant of that.
70 */
71
72 void SaslConnection::close()
73 {
74     if ( state() == Invalid )
75         return;
76
77     Endpoint client = peer();
78     Connection::close();
79
80     if ( !u || client.protocol() == Endpoint::Unix ||
81          !Configuration::toggle( Configuration::Security ) )
82         return;
83
84     Query * q = new Query(
85         "insert into connections "
86         "(username,address,port,mechanism,authfailures,"
87         "syntaxerrors,started_at,ended_at) "
88         "values ($1,$2,$3,$4,$5,$6,"
89         "$7::interval + 'epoch'::timestamptz,"
90         "$8::interval + 'epoch'::timestamptz)", 0
91     );
92
93     q->bind( 1, u->login() );
94     q->bind( 2, client.address() );
95     q->bind( 3, client.port() );
96     q->bind( 4, m );
97     q->bind( 5, af );
98     q->bind( 6, sf );
99     q->bind( 7, s );
100     q->bind( 8, (uint)time( 0 ) );
101     q->execute();
102 }
103
104
105 /*! Used to count authentication failures for logging and
106     statistics.
107 */
108
109 void SaslConnection::recordAuthenticationFailure()
110 {
111     af++;
112 }
113
114
115 /*! Used to count protocol syntax errors for logging and
116     statistics.
117 */
118
119 void SaslConnection::recordSyntaxError()
120 {
121     sf++;
122 }