aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services
diff options
context:
space:
mode:
authordiva2009-06-17 03:52:39 +0000
committerdiva2009-06-17 03:52:39 +0000
commitce7de3581cd678dd09227bdfde94fefb779f5a86 (patch)
tree2eab5b5424e8463d30cdc918604629fe3fe08cc5 /OpenSim/Services
parentMoving these nice HG connectors to their homes. (diff)
downloadopensim-SC-ce7de3581cd678dd09227bdfde94fefb779f5a86.zip
opensim-SC-ce7de3581cd678dd09227bdfde94fefb779f5a86.tar.gz
opensim-SC-ce7de3581cd678dd09227bdfde94fefb779f5a86.tar.bz2
opensim-SC-ce7de3581cd678dd09227bdfde94fefb779f5a86.tar.xz
Implementation of a simple authentication service + in connector in route to making HGInventory (client access) work in standalone again. This is the refactoring of what was/is there, but done in the new model. Not complete yet, but key authentication works. It should be enough to make HGInventory work again soon.
Diffstat (limited to '')
-rw-r--r--OpenSim/Services/AuthenticationService/AuthenticationService.cs181
-rw-r--r--OpenSim/Services/Interfaces/IAuthenticationService.cs30
2 files changed, 191 insertions, 20 deletions
diff --git a/OpenSim/Services/AuthenticationService/AuthenticationService.cs b/OpenSim/Services/AuthenticationService/AuthenticationService.cs
index 3eaa03d..6eaf0b0 100644
--- a/OpenSim/Services/AuthenticationService/AuthenticationService.cs
+++ b/OpenSim/Services/AuthenticationService/AuthenticationService.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic;
29using System.Reflection; 30using System.Reflection;
30using Nini.Config; 31using Nini.Config;
31using log4net; 32using log4net;
@@ -37,34 +38,196 @@ using OpenMetaverse;
37 38
38namespace OpenSim.Services.AuthenticationService 39namespace OpenSim.Services.AuthenticationService
39{ 40{
40 public class AuthenticationService : ServiceBase, IAuthenticationService 41 /// <summary>
42 /// Simple authentication service implementation dealing only with users.
43 /// It uses the user DB directly to access user information.
44 /// It takes two config vars:
45 /// - Authenticate = {true|false} : to do or not to do authentication
46 /// - Authority = string like "osgrid.org" : this identity authority
47 /// that will be called back for identity verification
48 /// </summary>
49 public class HGAuthenticationService : ServiceBase, IAuthenticationService
41 { 50 {
42 public AuthenticationService(IConfigSource config) : base(config) 51 private static readonly ILog m_log
52 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53
54 protected IUserDataPlugin m_Database;
55 protected string m_AuthorityURL;
56 protected bool m_PerformAuthentication;
57 protected Dictionary<UUID, List<string>> m_UserKeys = new Dictionary<UUID, List<string>>();
58
59
60 public HGAuthenticationService(IConfigSource config) : base(config)
43 { 61 {
62 string dllName = String.Empty;
63 string connString = String.Empty;
64
65 //
66 // Try reading the [DatabaseService] section first, if it exists
67 //
68 IConfig dbConfig = config.Configs["DatabaseService"];
69 if (dbConfig != null)
70 {
71 dllName = dbConfig.GetString("StorageProvider", String.Empty);
72 connString = dbConfig.GetString("ConnectionString", String.Empty);
73 }
74
75 //
76 // Try reading the more specific [InventoryService] section, if it exists
77 //
78 IConfig authConfig = config.Configs["AuthenticationService"];
79 if (authConfig != null)
80 {
81 dllName = authConfig.GetString("StorageProvider", dllName);
82 connString = authConfig.GetString("ConnectionString", connString);
83
84 m_PerformAuthentication = authConfig.GetBoolean("Authenticate", true);
85 m_AuthorityURL = "http://" + authConfig.GetString("Authority", "localhost");
86 }
87
88 //
89 // We tried, but this doesn't exist. We can't proceed.
90 //
91 if (dllName.Equals(String.Empty))
92 throw new Exception("No InventoryService configuration");
93
94 m_Database = LoadPlugin<IUserDataPlugin>(dllName);
95 if (m_Database == null)
96 throw new Exception("Could not find a storage interface in the given module");
97
98 m_Database.Initialise(connString);
99 }
100
101 /// <summary>
102 /// This implementation only authenticates users.
103 /// </summary>
104 /// <param name="principalID"></param>
105 /// <param name="password"></param>
106 /// <returns></returns>
107 public bool Authenticate(UUID principalID, string password)
108 {
109 if (!m_PerformAuthentication)
110 return true;
111
112 UserProfileData profile = m_Database.GetUserByUUID(principalID);
113 bool passwordSuccess = false;
114 m_log.InfoFormat("[AUTH]: Authenticating {0} {1} ({2})", profile.FirstName, profile.SurName, profile.ID);
115
116 // we do this to get our hash in a form that the server password code can consume
117 // when the web-login-form submits the password in the clear (supposed to be over SSL!)
118 if (!password.StartsWith("$1$"))
119 password = "$1$" + Util.Md5Hash(password);
120
121 password = password.Remove(0, 3); //remove $1$
122
123 string s = Util.Md5Hash(password + ":" + profile.PasswordSalt);
124 // Testing...
125 //m_log.Info("[LOGIN]: SubHash:" + s + " userprofile:" + profile.passwordHash);
126 //m_log.Info("[LOGIN]: userprofile:" + profile.passwordHash + " SubCT:" + password);
127
128 passwordSuccess = (profile.PasswordHash.Equals(s.ToString(), StringComparison.InvariantCultureIgnoreCase)
129 || profile.PasswordHash.Equals(password, StringComparison.InvariantCultureIgnoreCase));
130
131 return passwordSuccess;
44 } 132 }
45 133
46 public UUID AllocateUserSession(UUID userID) 134 /// <summary>
135 /// This generates authorization keys in the form
136 /// http://authority/uuid
137 /// after verifying that the caller is, indeed, authorized to request a key
138 /// </summary>
139 /// <param name="userID">The principal ID requesting the new key</param>
140 /// <param name="authToken">The original authorization token for that principal, obtained during login</param>
141 /// <returns></returns>
142 public string GetKey(UUID principalID, string authToken)
47 { 143 {
48 return UUID.Zero; 144 UserProfileData profile = m_Database.GetUserByUUID(principalID);
145 string newKey = string.Empty;
146
147 if (profile != null)
148 {
149 m_log.DebugFormat("[AUTH]: stored auth token is {0}. Given token is {1}", profile.WebLoginKey.ToString(), authToken);
150 // I'm overloading webloginkey for this, so that no changes are needed in the DB
151 // The uses of webloginkey are fairly mutually exclusive
152 if (profile.WebLoginKey.ToString().Equals(authToken))
153 {
154 newKey = UUID.Random().ToString();
155 List<string> keys;
156 lock (m_UserKeys)
157 {
158 if (m_UserKeys.ContainsKey(principalID))
159 {
160 keys = m_UserKeys[principalID];
161 }
162 else
163 {
164 keys = new List<string>();
165 m_UserKeys.Add(principalID, keys);
166 }
167 keys.Add(newKey);
168 }
169 m_log.InfoFormat("[AUTH]: Successfully generated new auth key for {0}", principalID);
170 }
171 else
172 m_log.Warn("[AUTH]: Unauthorized key generation request. Denying new key.");
173 }
174 else
175 m_log.Warn("[AUTH]: Principal not found.");
176
177 return m_AuthorityURL + newKey;
49 } 178 }
50 179
51 public string GetUserKey(UUID userID, string authToken) 180 /// <summary>
181 /// This verifies the uuid portion of the key given out by GenerateKey
182 /// </summary>
183 /// <param name="userID"></param>
184 /// <param name="key"></param>
185 /// <returns></returns>
186 public bool VerifyKey(UUID userID, string key)
52 { 187 {
53 return String.Empty; 188 lock (m_UserKeys)
189 {
190 if (m_UserKeys.ContainsKey(userID))
191 {
192 List<string> keys = m_UserKeys[userID];
193 if (keys.Contains(key))
194 {
195 // Keys are one-time only, so remove it
196 keys.Remove(key);
197 return true;
198 }
199 return false;
200 }
201 else
202 return false;
203 }
54 } 204 }
55 205
56 public bool VerifyUserKey(UUID userID, string key) 206 public UUID AllocateUserSession(UUID userID)
57 { 207 {
58 return false; 208 // Not implemented yet
209 return UUID.Zero;
59 } 210 }
60 211
61 public bool VerifyUserSession(UUID userID, UUID session) 212 public bool VerifyUserSession(UUID userID, UUID sessionID)
62 { 213 {
214 UserProfileData userProfile = m_Database.GetUserByUUID(userID);
215
216 if (userProfile != null && userProfile.CurrentAgent != null)
217 {
218 m_log.DebugFormat("[AUTH]: Verifying session {0} for {1}; current session {2}", sessionID, userID, userProfile.CurrentAgent.SessionID);
219 if (userProfile.CurrentAgent.SessionID == sessionID)
220 {
221 return true;
222 }
223 }
224
63 return false; 225 return false;
64 } 226 }
65 227
66 public void DestroyUserSession(UUID userID) 228 public void DestroyUserSession(UUID userID)
67 { 229 {
230 // Not implemented yet
68 } 231 }
69 } 232 }
70} 233}
diff --git a/OpenSim/Services/Interfaces/IAuthenticationService.cs b/OpenSim/Services/Interfaces/IAuthenticationService.cs
index 35831c1..fa45cbc 100644
--- a/OpenSim/Services/Interfaces/IAuthenticationService.cs
+++ b/OpenSim/Services/Interfaces/IAuthenticationService.cs
@@ -30,31 +30,39 @@ using OpenMetaverse;
30 30
31namespace OpenSim.Services.Interfaces 31namespace OpenSim.Services.Interfaces
32{ 32{
33 // Generic Authentication service used for identifying
34 // and authenticating principals.
35 // Principals may be clients acting on users' behalf,
36 // or any other components that need
37 // verifiable identification.
38 //
33 public interface IAuthenticationService 39 public interface IAuthenticationService
34 { 40 {
35 // Create a new user session. If one exists, it is cleared 41 // Check the pricipal's password
36 // 42 //
37 UUID AllocateUserSession(UUID userID); 43 bool Authenticate(UUID principalID, string password);
38 44
39 // Get a user key from an authentication token. This must be 45 // Get a service key given that principal's
40 // done before the session allocated above is considered valid. 46 // authentication token (master key).
41 // Repeated calls to this method with the same auth token will
42 // create different keys and invalidate the previous ne.
43 // 47 //
44 string GetUserKey(UUID userID, string authToken); 48 string GetKey(UUID principalID, string authToken);
45 49
46 // Verify that a user key is valid 50 // Verify that a principal key is valid
47 // 51 //
48 bool VerifyUserKey(UUID userID, string key); 52 bool VerifyKey(UUID principalID, string key);
53
54 // Create a new user session. If one exists, it is cleared
55 //
56 UUID AllocateUserSession(UUID userID);
49 57
50 // Verify that a user session ID is valid. A session ID is 58 // Verify that a user session ID is valid. A session ID is
51 // considered valid when a user has successfully authenticated 59 // considered valid when a user has successfully authenticated
52 // at least one time inside that session. 60 // at least one time inside that session.
53 // 61 //
54 bool VerifyUserSession(UUID userID, UUID session); 62 bool VerifyUserSession(UUID principalID, UUID session);
55 63
56 // Remove a user session identifier and deauthenticate the user 64 // Remove a user session identifier and deauthenticate the user
57 // 65 //
58 void DestroyUserSession(UUID userID); 66 void DestroyUserSession(UUID principalID);
59 } 67 }
60} 68}