/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * */ #include "wvstreamsdebuggerserver.h" #include "wvunixsocket.h" #include "wvtcplistener.h" #include "wvunixlistener.h" void WvStreamsDebuggerServer::Connection::choose_salt() { const int salt_size = 8; const int salt_alphabet_size = 26+26+10; const char salt_chars[salt_alphabet_size+1] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; salt.setsize(salt_size+1); for (int i=0; iset_wsname("wsd listener on %s", unix_addr); unix_listener->onaccept( wv::bind(&WvStreamsDebuggerServer::unix_listener_cb, this, _1)); unix_listener->setclosecallback( wv::bind(&WvStreamsDebuggerServer::unix_listener_close_cb, this)); streams.append(unix_listener, true, "debugger unix listener"); log("Listening on %s\n", unix_addr); } #endif if (tcp_addr != WvIPPortAddr()) { tcp_listener = new WvTCPListener(tcp_addr); tcp_listener->set_wsname("wsd listener on %s", tcp_addr); tcp_listener->onaccept( wv::bind(&WvStreamsDebuggerServer::tcp_listener_cb, this, _1)); tcp_listener->setclosecallback( wv::bind(&WvStreamsDebuggerServer::tcp_listener_close_cb, this)); streams.append(tcp_listener, true, "debugger tcp listener"); log("Listening on %s\n", tcp_addr); } } WvStreamsDebuggerServer::~WvStreamsDebuggerServer() { WvIStreamList::globallist.unlink(&streams); } #ifndef _WIN32 void WvStreamsDebuggerServer::unix_listener_cb(IWvStream *unix_conn) { log("Accepted connection from %s\n", *unix_conn->src()); Connection *conn = new Connection(unix_conn); conn->setcallback(wv::bind(&WvStreamsDebuggerServer::ready_cb, this, wv::ref(*conn))); streams.append(conn, true, "debugger unix connection"); } void WvStreamsDebuggerServer::unix_listener_close_cb() { log("Listener on %s closing\n", *unix_listener->src()); } #endif void WvStreamsDebuggerServer::tcp_listener_cb(IWvStream *tcp_conn) { log("Accepted connection from %s\n", *tcp_conn->src()); Connection *conn = new Connection(tcp_conn); conn->setcallback(wv::bind(&WvStreamsDebuggerServer::ready_cb, this, wv::ref(*conn))); streams.append(conn, true, "debugger tcp connection"); } void WvStreamsDebuggerServer::tcp_listener_close_cb() { log("Listener on %s closing\n", *tcp_listener->src()); } void WvStreamsDebuggerServer::auth_request_cb(Connection &s) { s.choose_salt(); s.send("AUTH", s.salt); s.setcallback(wv::bind(&WvStreamsDebuggerServer::auth_response_cb, this, wv::ref(s))); } void WvStreamsDebuggerServer::auth_response_cb(Connection &s) { const char *line = s.getline(); if (line == NULL) return; WvStringList args; wvtcl_decode(args, line); WvString username = args.popstr(); WvString encoded_salted_password = args.popstr(); if (!auth_cb || !username || !encoded_salted_password || !auth_cb(username, s.salt, encoded_salted_password)) { s.send("ERROR", "Authentication failure"); s.setcallback(wv::bind(&WvStreamsDebuggerServer::auth_request_cb, this, wv::ref(s))); } else { s.send("OK", "Authenticated"); s.setcallback(wv::bind(&WvStreamsDebuggerServer::ready_cb, this, wv::ref(s))); } } void WvStreamsDebuggerServer::ready_cb(Connection &s) { const char *line = s.getline(); if (line == NULL) return; WvStringList args; wvtcl_decode(args, line); WvString cmd = args.popstr(); if (!cmd) { s.send("ERROR", "Empty command"); return; } WvString result = s.debugger.run(cmd, args, wv::bind(&Connection::result_cb, &s, _1, _2)); if (!!result) s.send("ERROR", result); else s.send("OK", "Command successful"); }