Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members | Related Pages | Examples

vos/metaobjects/misc/login.cc

Go to the documentation of this file.
00001 /* $Id: login.cc,v 1.12 2003/07/23 00:17:27 reed Exp $ */
00002 
00003 
00004 /* This file was generated by otd2cpp.pl
00005 
00006     Copyright (C) 2002 Peter Amstutz <tetron@interreality.org>
00007 
00008     This library is free software; you can redistribute it and/or
00009     modify it under the terms of the GNU Lesser General Public
00010     License as published by the Free Software Foundation; either
00011     version 2 of the License, or (at your option) any later version.
00012 
00013     This library is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016     Lesser General Public License for more details.
00017 
00018     You should have received a copy of the GNU Lesser General Public
00019     License along with this library; if not, write to the Free Software
00020     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
00021 
00022 */
00023 
00024 /** @file login.cc Code: a MetaObject for Login object types. */
00025 
00026 #include <vos/corelibs/vos/vos.hh>
00027 #include <vos/metaobjects/property/property.hh>
00028 #include "login.hh"
00029 #include "md5.hh"
00030 
00031 class MD5;
00032 
00033 /* Constructors */
00034 
00035 LocalLogin::LocalLogin(MetaObject* s) : MetaObject(s) {
00036     addMessageHandler<LocalLogin>("misc:request-login", this, &LocalLogin::handleRequestLogin);
00037     addMessageHandler<LocalLogin>("misc:login-challenge-reply", this, &LocalLogin::handleLoginChallengeReply);
00038 }
00039 
00040 LocalLogin::~LocalLogin() {
00041 }
00042 
00043 RemoteLogin::RemoteLogin(MetaObject* s) : MetaObject(s) {
00044     addUpdateHandler<RemoteLogin>("misc:request-login-challenge", this, &RemoteLogin::handleRequestLoginChallenge);
00045     addUpdateHandler<RemoteLogin>("misc:login-result", this, &RemoteLogin::handleLoginResult);
00046 }
00047 
00048 RemoteLogin::~RemoteLogin() {
00049 }
00050 
00051 const string LocalLogin::getType() {
00052     return string("misc:login");
00053 }
00054 
00055 const string RemoteLogin::getType() {
00056     return string("misc:login");
00057 }
00058 
00059 
00060 /* Register extenders with libvos MetaFactory */
00061 void RemoteLogin::registerExtenders() {
00062     static bool done = false;
00063     if(! done) {
00064     RemoteSite::addRemoteObjectExtension(typeid(RemoteLogin).name(), &RemoteLogin::new_RemoteLogin);
00065     RemoteSite::addRemoteObjectExtension("misc:login", &RemoteLogin::new_RemoteLogin);
00066     done = true;
00067     }
00068 }
00069 
00070 
00071 /* Message Handlers:  */
00072 
00073     /* TODO you might wantto override some of these methods in LocalLogin  and RemoteLogin */
00074 
00075     /* Handle message request-login */
00076 
00077 void LocalLogin::handleRequestLogin(Message* m) {
00078     /* Fields in this message are:
00079         username (The username to authenticate)
00080     */
00081 
00082     /* Replies are:
00083         request-login-challenge (Challenge the requester with a random string.  ) Fields: nonce (  A random string.);
00084     */
00085         try {
00086             pREF(Message*, reply, new Message(),
00087                 LocalVobject::initReply(this, reply, m, "misc:request-login-challenge");
00088                 rREF(Vobject&, from, Vobject::findObjectFromRoot(m->getFrom()),
00089 
00090                      char s[64];
00091                      snprintf(s, sizeof(s), "%li", rand());
00092                      nonceMap[m->getSourceSite()].username = m->getField("username").value;
00093                      nonceMap[m->getSourceSite()].timestamp = time(0);
00094                      nonceMap[m->getSourceSite()].nonce = s;
00095                      reply->insertField(-1, "nonce", s);
00096 
00097                      from.sendMessage(reply);
00098                 );
00099             );
00100         } catch(Message::NoSuchFieldError e) {
00101             /* A field wasn't found */
00102         }
00103 
00104 }
00105 
00106     /* Handle message login-challenge-reply */
00107 
00108 void LocalLogin::handleLoginChallengeReply(Message* m) {
00109     /* Fields in this message are:
00110         hash (The MD5 hash of the the user's password appended to the challenge string.  )
00111     */
00112 
00113     /* Replies are:
00114         login-result (The user is informed if they have been authenticated or no.  ) Fields: result (  "success" if the user was accepted, or some other string  describing the error.);
00115     */
00116 
00117         try {
00118             pREF(Message*, reply, new Message(),
00119                 LocalVobject::initReply(this, reply, m, "misc:login-result");
00120                 rREF(Vobject&, from, Vobject::findObjectFromRoot(m->getFrom()),
00121 
00122                      if(time(0) - nonceMap[m->getSourceSite()].timestamp > 60) {
00123                          reply->insertField(-1, "result", "Stale nonce (waited too long to reply).  Try again.");
00124                      } else {
00125                          string app = nonceMap[m->getSourceSite()].nonce;
00126                          try {
00127                              app += getPassword(nonceMap[m->getSourceSite()].username);
00128                              _MD5 md5;
00129                              md5.update((unsigned char*)app.c_str(), app.size());
00130                              md5.finalize();
00131                              if(m->getField("hash").value == md5.hex_digest()) {
00132                                  reply->insertField(-1, "result", "success");
00133                              } else {
00134                                  reply->insertField(-1, "result", "Bad username or password ");
00135                              }
00136                          } catch(BadUsernameError x) {
00137                              reply->insertField(-1, "result", string("Bad username or password ") + x.what());
00138                          }
00139                      }
00140 
00141                      string username = nonceMap[m->getSourceSite()].username;
00142                      nonceMap.erase(m->getSourceSite());
00143 
00144                      from.sendMessage(reply);
00145 
00146                      if(reply->getField("result").value == "success")
00147                          notifyAuthenticated(username, m->getSourceSite());
00148                 );
00149             );
00150         } catch(Message::NoSuchFieldError e) {
00151             /* A field wasn't found */
00152         }
00153 
00154 }
00155 
00156 /* Remote Actuators: */
00157 
00158 /* Do request-login. */
00159 
00160 bool RemoteLogin::doRequestLogin(const string& username, const string& passwd) {
00161     success = false;
00162     password = passwd;
00163 
00164     pREF(Message*, m, new Message(),
00165          rREF(LocalSite&, ls, RemoteVobject::initFields(this, m, "misc:request-login", true),
00166 
00167               m->insertField(-1, "username", username);
00168 
00169               sendMessage(m);
00170               rREF(RemoteSite&, site, dynamic_cast<RemoteSite&>(getSite()),
00171                    pREF(Message*, n, ls.waitFor(m->getNonce(), &site), );
00172                   );
00173              );
00174         );
00175     return success;
00176 }
00177 
00178 /* Generators for factory */
00179 
00180 MetaObject* RemoteLogin::new_RemoteLogin(MetaObject* s, const string& type) {
00181     return new RemoteLogin(s);
00182 }
00183 
00184 /* Handle request-login-challenge. */
00185 
00186 void RemoteLogin::handleRequestLoginChallenge(Message* m) {
00187     try {
00188         pREF(Message*, p, new Message(),
00189              rREF(LocalSite&, ls, RemoteVobject::initFields(this, p, "misc:login-challenge-reply", true),
00190 
00191                   string nonce = m->getField("nonce").value;
00192                   nonce += password;
00193                   _MD5 md5;
00194                   md5.update((unsigned char*)nonce.c_str(), nonce.size());
00195                   md5.finalize();
00196                   p->insertField(-1, "hash", md5.hex_digest());
00197 
00198                   sendMessage(p);
00199                   rREF(RemoteSite&, site, dynamic_cast<RemoteSite&>(getSite()),
00200                        pREF(Message*, x, ls.waitFor(p->getNonce(), &site), );
00201                       );
00202                  );
00203             );
00204     } catch(Message::NoSuchFieldError) {}
00205 }
00206 
00207 void RemoteLogin::handleLoginResult(Message* m) {
00208     if(m->getField("result").value == "success") success=true;
00209 }

Generated on Tue Aug 12 03:55:44 2003 for Interreality Project - VOS by doxygen 1.3.2