wvstreamsdebuggerserver.cc

00001 /*
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  * 
00005  */
00006 #include "wvstreamsdebuggerserver.h"
00007 #include "wvunixsocket.h"
00008 #include "wvtcp.h"
00009 
00010 void WvStreamsDebuggerServer::Connection::choose_salt()
00011 {
00012     const int salt_size = 8;
00013     const int salt_alphabet_size = 26+26+10;
00014     const char salt_chars[salt_alphabet_size+1] =
00015         "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
00016     
00017     salt.setsize(salt_size+1);
00018     for (int i=0; i<salt_size; ++i)
00019         salt.edit()[i] = salt_chars[rand() % salt_alphabet_size];
00020     salt.edit()[salt_size] = '\0';
00021 }
00022 
00023 
00024 WvStreamsDebuggerServer::Connection::Connection(WvStream *s) :
00025     WvStreamClone(s)
00026 {
00027 }
00028 
00029 
00030 void WvStreamsDebuggerServer::Connection::result_cb(WvStringParm,
00031         WvStringList &results)
00032 {
00033     send("-", results);
00034 }
00035 
00036 
00037 void WvStreamsDebuggerServer::Connection::send(WvStringParm code,
00038         WvStringParm result)
00039 {
00040     WvStringList results;
00041     results.append(result);
00042     send(code, results);
00043 }
00044 
00045 
00046 void WvStreamsDebuggerServer::Connection::send(WvStringParm code,
00047         WvStringList &results)
00048 {
00049     print("%s %s\n", wvtcl_escape(code), wvtcl_encode(results));
00050 }
00051 
00052 
00053 WvStreamsDebuggerServer::WvStreamsDebuggerServer(const WvUnixAddr &unix_addr,
00054         AuthCallback _auth_cb,
00055         const WvIPPortAddr &tcp_addr) :
00056     log("WvStreamsDebuggerServer", WvLog::Debug3),
00057     unix_listener(NULL),
00058     tcp_listener(NULL),
00059     auth_cb(_auth_cb)
00060 {
00061     WvIStreamList::globallist.append(&streams, false);
00062 
00063 #ifndef _WIN32
00064     if (true)
00065     {
00066         unix_listener = new WvUnixListener(unix_addr, 0700);
00067         unix_listener->set_wsname("wsd listener on %s", unix_addr);
00068         unix_listener->setcallback(WvStreamCallback(this,
00069                 &WvStreamsDebuggerServer::unix_listener_cb), NULL);
00070         unix_listener->setclosecallback(IWvStreamCallback(this,
00071                 &WvStreamsDebuggerServer::unix_listener_close_cb));
00072         streams.append(unix_listener, true);
00073         log("Listening on %s\n", unix_addr);
00074     }
00075 #endif
00076     
00077     if (tcp_addr != WvIPPortAddr())
00078     {
00079         tcp_listener = new WvTCPListener(tcp_addr);
00080         tcp_listener->set_wsname("wsd listener on %s", tcp_addr);
00081         tcp_listener->setcallback(WvStreamCallback(this,
00082                 &WvStreamsDebuggerServer::tcp_listener_cb), NULL);
00083         tcp_listener->setclosecallback(IWvStreamCallback(this,
00084                 &WvStreamsDebuggerServer::tcp_listener_close_cb));
00085         streams.append(tcp_listener, true);
00086         log("Listening on %s\n", tcp_addr);
00087     }
00088 }
00089 
00090 
00091 WvStreamsDebuggerServer::~WvStreamsDebuggerServer()
00092 {
00093     WvIStreamList::globallist.unlink(&streams);
00094 }
00095 
00096 
00097 #ifndef _WIN32
00098 void WvStreamsDebuggerServer::unix_listener_cb(WvStream &, void *)
00099 {
00100     WvUnixConn *unix_conn = unix_listener->accept();
00101     if (!unix_conn)
00102         return;
00103     log("Accepted connection from %s\n", *unix_conn->src());
00104     Connection *conn = new Connection(unix_conn);
00105     conn->setcallback(WvStreamCallback(this,
00106             &WvStreamsDebuggerServer::ready_cb), NULL);
00107     streams.append(conn, true);
00108 }
00109 
00110 
00111 void WvStreamsDebuggerServer::unix_listener_close_cb(WvStream &)
00112 {
00113     log("Listener on %s closing\n", *unix_listener->src());
00114 }
00115 #endif
00116 
00117 void WvStreamsDebuggerServer::tcp_listener_cb(WvStream &, void *)
00118 {
00119     WvTCPConn *tcp_conn = tcp_listener->accept();
00120     if (!tcp_conn)
00121         return;
00122     log("Accepted connection from %s\n", *tcp_conn->src());
00123     Connection *conn = new Connection(tcp_conn);
00124     conn->setcallback(WvStreamCallback(this,
00125             &WvStreamsDebuggerServer::ready_cb), NULL);
00126     streams.append(conn, true);
00127 }
00128 
00129 
00130 void WvStreamsDebuggerServer::tcp_listener_close_cb(WvStream &)
00131 {
00132     log("Listener on %s closing\n", *tcp_listener->src());
00133 }
00134 
00135 
00136 void WvStreamsDebuggerServer::auth_request_cb(WvStream &_s, void *)
00137 {
00138     Connection &s = static_cast<Connection &>(_s);
00139     
00140     s.choose_salt();
00141     s.send("AUTH", s.salt);
00142     
00143     s.setcallback(WvStreamCallback(this,
00144             &WvStreamsDebuggerServer::auth_response_cb), NULL);
00145 }
00146 
00147 
00148 void WvStreamsDebuggerServer::auth_response_cb(WvStream &_s, void *)
00149 {
00150     Connection &s = static_cast<Connection &>(_s);
00151     const char *line = s.getline();
00152     if (line == NULL)
00153         return;
00154         
00155     WvStringList args;
00156     wvtcl_decode(args, line);
00157     
00158     WvString username = args.popstr();
00159     WvString encoded_salted_password = args.popstr();
00160     
00161     if (!auth_cb || !username || !encoded_salted_password
00162         || !auth_cb(username, s.salt, encoded_salted_password))
00163     {
00164         s.send("ERROR", "Authentication failure");
00165         s.setcallback(WvStreamCallback(this,
00166                 &WvStreamsDebuggerServer::auth_request_cb), NULL);
00167     }
00168     else
00169     {
00170         s.send("OK", "Authenticated");
00171         s.setcallback(WvStreamCallback(this,
00172                 &WvStreamsDebuggerServer::ready_cb), NULL);
00173     }
00174 }
00175 
00176 
00177 void WvStreamsDebuggerServer::ready_cb(WvStream &_s, void *)
00178 {
00179     Connection &s = static_cast<Connection &>(_s);
00180     const char *line = s.getline();
00181     if (line == NULL)
00182         return;
00183         
00184     WvStringList args;
00185     wvtcl_decode(args, line);
00186     
00187     WvString cmd = args.popstr();
00188     if (!cmd)
00189     {
00190         s.send("ERROR", "Empty command");
00191         return;
00192     }
00193     
00194     WvString result = s.debugger.run(cmd, args,
00195         WvStreamsDebugger::ResultCallback(&s, &Connection::result_cb));
00196     if (!!result)
00197         s.send("ERROR", result);
00198     else
00199         s.send("OK", "Command successful");
00200 }
00201 
00202 
00203 void WvStreamsDebuggerServer::close_cb(WvStream &_s)
00204 {
00205     streams.unlink(&_s);
00206 }

Generated on Thu Jan 24 16:50:57 2008 for WvStreams by  doxygen 1.5.4