Stun Server  Compliant with the latest RFCs including 5389, 5769, and 5780
discover the local host's own external IP address
sampleauthprovider.h
Go to the documentation of this file.
1 /*
2  Copyright 2011 John Selbie
3 
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 #ifndef SAMPLE_STUN_AUTH_PROVIDER
18 #define SAMPLE_STUN_AUTH_PROVIDER
19 
20 
21 #if 0
22 
23 sampleauthprovider.h and sampleauthprovider.cpp
24 
25 The stun library code knows how to generate and validate message integrity attributes
26 inside stun attributes. But it relies on an implemented "auth provider" to actually
27 confirm a username and supply the password key.
28 
29 It is out of the scope of this release to implement an authentication provider that
30 will work for everyone. One deployment may store usernames and passwords in a database.
31 Other deployments may rely on a ticketing service library.
32 
33 RFC 5389 specifies two authentication mechanisms for STUN. It is recommended
34 that you read it before deciding how timplement
35 
36 "Short term credentials" is simply the case where a stun binding request
37 sent from client to server contains a message integrity attribute. The message
38 integrity attribute is simply an attribute that contins an HMAC-SHA1 hash of
39 the stun msesage itself. The stun message should also contain a username attribute.
40 The 'key' field of the HMAC operation is a private password associated with the
41 username in the binding request.
42 
43 "Long term credentials" is similar to short term credentials but involves a challenge
44 response phase to prevent replay attacks. This is the recommended mechanism for
45 STUN authentication.
46 
47 We can also support "ticket based credentials". This is not a mechanism specified
48 by the STUN RFC, but has been known to work in various scenarios. The username
49 and/or realm fields are overloaded to represent a "ticket" signed by an external
50 entity. The auth provider knows how to validate the ticket.
51 
52 We can also implement "legacy password" authentication. This is simply the password
53 (with or without a username and realm) embedded in the clear in the stun binding
54 request. Not recommended unless the transport type is TLS.
55 
56 Implementing authentication is simply implementing a class that implements
57 IStunAuth. IStunAuth has only one method called "DoAuthCheck". DoAuthCheck
58 is called for each incoming Stun Message. It takes one input parameter pointer
59 to a struct instance of type AuthAttributes) and one "out" param which is a struct
60 for handing back authentication tokens back to the server.
61 
62  HRESULT DoAuthCheck(/*in*/ AuthAttributes* pAuthAttributes, /*out*/ AuthResponse* pResponse);
63 
64 The AuthAttributes struct representes various attribute values received in a STUN
65 binding request. They are outlined as follows:
66 
67  char szUser[MAX_STUN_AUTH_STRING_SIZE]; // the user name attribute in the request (if available)
68  char szRealm[MAX_STUN_AUTH_STRING_SIZE]; // the realm attribute in the request (if available)
69  char szNonce[MAX_STUN_AUTH_STRING_SIZE]; // the nonce attribute in the request (if available)
70  char szLegacyPassword[MAX_STUN_AUTH_STRING_SIZE]; // this is not the password used in the message integrity, this is if the request provided a password in the clear (ala rfc 3478). Not recommended, but auth providers can use it if they want.
71  bool fMessageIntegrityPresent; // true if there was a message integrity field
72 
73 The implementation of DoAuthCheck needs to decide how to handle the AuthAttributes
74 and then pass back a series of results and codes through the provided AuthResponse
75 paramter.
76 
77 The AuthResponse parameter is for indicating to the server how to authenticate a
78 message integrity attribute. The implementation needs to set the following fieds
79 as appropriate:
80 
81  AuthResponseType responseType;
82  responseType must be set to one of the following values
83  // Allow - Indicates to the server to send back a response and that no
84  additional validation on the message integrity field is needed
85 
86  // AllowConditional - Indicates to the server that a response can be sent
87  as lone as the message integrity attribute in the stun request
88  is valid with respect to szPassword (and szUserName and szNonce if in long term cred mode)
89  If the message integrity attribute is deemed invalid, then
90  a 401 is sent back instead of a binding response.
91 
92  // Reject - Indicates that the server should send back a 400 without any
93  additional attributes
94 
95  // Unauthorized - Indicates that the server should send back a 401. In long term
96  cred mode, this will also send back the szNonce and szRealm fields
97  as attributes.
98 
99  // StaleNonce - Indicates that the request was likely valid, but the nonce
100  attribute valid has expired
101 
102  AuthCredentialMechanism authCredMech;
103  Is either set to AuthShortTerm or AuthLongTerm to indicate to the server
104  how to generate and validate message integrity fields
105 
106  szPassword
107  Ignored if _responseType is anything other than AllowConditional.
108  server will not send this back as an attribute. Instead it is used
109  for validating and generating message integrity attributes in the
110  stun messages.
111 
112  szRealm
113  Ignored if using short term credentials. Otherwise, it should be
114  the realm field used for generating and validating message integrity fields.
115  It will almost always need to be sent back in error responses to
116  the client.
117 
118  szNonce
119  A new nonce for subsequent requests in the event this request can not
120 
121 
122  DoAuthCheck should return S_OK unless a fatal error occurs. If DoAuthCheck returns
123  a failure code, then
124 
125 
126  To have the server host an instance of an IStunAuth implementation, modify
127  CStunServer::Initialize and CTCPServer::Initialize to create an instance of your class and initialize
128  _spAuth as appropriate.
129 
130 #endif
131 
132 
133 
135  public CBasicRefCount,
136  public CObjectFactory<CShortTermAuth>,
137  public IStunAuth
138 {
139 public:
140  virtual HRESULT DoAuthCheck(AuthAttributes* pAuthAttributes, AuthResponse* pResponse);
142 };
143 
144 
146  public CBasicRefCount,
147  public CObjectFactory<CLongTermAuth>,
148  public IStunAuth
149 {
150 private:
151  void HmacToString(uint8_t* hmacvalue, char* pszResult);
152  HRESULT CreateNonce(char* pszNonce);
153  HRESULT ValidateNonce(char* pszNonce);
154 
155 public:
156 
157  virtual HRESULT DoAuthCheck(AuthAttributes* pAuthAttributes, AuthResponse* pResponse);
159 };
160 
161 
162 #endif
163 
#define S_OK
Definition: hresult.h:46
AuthCredentialMechanism
Definition: stunauth.h:37
#define ADDREF_AND_RELEASE_IMPL()
HRESULT Initialize(const CStunServerConfig &config)
Definition: tcpserver.cpp:830
const uint32_t MAX_STUN_AUTH_STRING_SIZE
Definition: stunauth.h:22
int32_t HRESULT
Definition: hresult.h:22
AuthResponseType
Definition: stunauth.h:43
virtual HRESULT DoAuthCheck(AuthAttributes *pAuthAttributes, AuthResponse *pResponse)
HRESULT Initialize(const CStunServerConfig &config)
Definition: server.cpp:95