diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2012-06-24 18:23:18 -0500 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2012-06-24 18:23:18 -0500 |
commit | e23898e185c0f639c6c6b98478b8b21f1ae83720 (patch) | |
tree | e5e2fd731ac59299cd68ed017d11f1ad9a9462d6 /servers/auth_server_lin/src/auth_conn.cpp | |
parent | 8dcfe72c396a6f0c4bafd2ed23ba52a475154ef2 (diff) | |
download | ulab-e23898e185c0f639c6c6b98478b8b21f1ae83720.tar.gz ulab-e23898e185c0f639c6c6b98478b8b21f1ae83720.zip |
Update protocol and implement LIST/BIND logic
Diffstat (limited to 'servers/auth_server_lin/src/auth_conn.cpp')
-rw-r--r-- | servers/auth_server_lin/src/auth_conn.cpp | 209 |
1 files changed, 196 insertions, 13 deletions
diff --git a/servers/auth_server_lin/src/auth_conn.cpp b/servers/auth_server_lin/src/auth_conn.cpp index 396218a..28b79fb 100644 --- a/servers/auth_server_lin/src/auth_conn.cpp +++ b/servers/auth_server_lin/src/auth_conn.cpp @@ -22,6 +22,8 @@ #include <stdlib.h> +#include <klocale.h> + #include "auth_conn.h" /* exception handling */ @@ -36,17 +38,40 @@ struct exit_exception { instance of this class. */ AuthSocket::AuthSocket(int sock, TQObject *parent, const char *name) : - TDEKerberosServerSocket( parent, name ), m_criticalSection(0) { + TDEKerberosServerSocket(parent, name), m_criticalSection(0), m_stationID(-1), m_config(static_cast<AuthServer*>(parent)->m_config), m_database(NULL), m_databaseStationsCursor(NULL) { setServiceName("remotefpga"); line = 0; connect(this, SIGNAL(connectionClosed()), SLOT(connectionClosedHandler())); - setSocket( sock ); + setSocket(sock); + + if (connectToDatabase() != 0) { + exit(1); + } } AuthSocket::~AuthSocket() { - // + if (m_databaseStationsCursor) { + delete m_databaseStationsCursor; + } + if (m_databaseServicesCursor) { + delete m_databaseServicesCursor; + } + if (m_databaseServiceTypesCursor) { + delete m_databaseServiceTypesCursor; + } + if (m_databasePermissionsCursor) { + delete m_databasePermissionsCursor; + } + if (m_databaseActivityCursor) { + delete m_databaseActivityCursor; + } + + if (m_database) { + m_database->close(); + delete m_database; + } } void AuthSocket::close() { @@ -56,6 +81,14 @@ void AuthSocket::close() { void AuthSocket::connectionClosedHandler() { printf("[DEBUG] Connection from %s closed\n\r", m_remoteHost.ascii()); + + // Update database + m_databaseActivityCursor->select(TQString("station='%1' AND username='%2' AND realmname='%3'").arg(m_stationID).arg(m_authenticatedUserName).arg(m_authenticatedRealmName)); + if (m_databaseActivityCursor->next()) { + m_databaseActivityCursor->primeDelete(); + m_databaseActivityCursor->del(true); + } + if (m_criticalSection > 0) { throw exit_exception(-1); } @@ -85,15 +118,92 @@ int AuthSocket::enterCommandLoop() { while (state() == TQSocket::Connected) { ds >> command; -printf("[RAJA DEBUG 500.0] Got command %s\n\r", command.ascii()); fflush(stdout); - if (command == "LIST") { - // Send list of available servers... - // RAJA FIXME - StationList slist; - ds << slist; - } - else { - ds << "ERRINVCMD"; + if (command != "") { + printf("[DEBUG] Got command %s from user %s@%s\n\r", command.ascii(), m_authenticatedUserName.ascii(), m_authenticatedRealmName.ascii()); fflush(stdout); + if (command == "LIST") { + // Send list of available servers... + m_slist.clear(); + + // Get all stations from the database + m_databaseStationsCursor->select(); + while (m_databaseStationsCursor->next()) { + bool authorized = false; + bool in_use = false; + + m_databasePermissionsCursor->select(TQString("station=%1").arg(m_databaseStationsCursor->value("pk").toInt())); + while (m_databasePermissionsCursor->next()) { + if (m_databasePermissionsCursor->value("username").toString() == m_authenticatedUserName) { + authorized = true; + } + } + m_databaseActivityCursor->select(TQString("station=%1").arg(m_databaseStationsCursor->value("pk").toInt())); + while (m_databaseActivityCursor->next()) { + if (m_databaseActivityCursor->value("username").toString() != "") { + in_use = true; + } + } + + if ((authorized) && (!in_use)) { + StationType st; + st.id = m_databaseStationsCursor->value("pk").toInt(); + st.name = m_databaseStationsCursor->value("name").toString(); + st.description = m_databaseStationsCursor->value("description").toString(); + m_databaseServicesCursor->select(TQString("station=%1").arg(m_databaseStationsCursor->value("pk").toInt())); + while (m_databaseServicesCursor->next()) { + m_databaseServiceTypesCursor->select(TQString("serviceid=%1").arg(m_databaseServicesCursor->value("servicetype").toInt())); + ServiceType svt; + if (m_databaseServiceTypesCursor->next()) { + svt.name = m_databaseServiceTypesCursor->value("name").toString(); + svt.description = m_databaseServiceTypesCursor->value("description").toString(); + } + if (svt.name == "") { + svt.name = i18n("<unknown>"); + } + if (svt.description == "") { + svt.description = i18n("<unknown>"); + } + st.services.append(svt); + } + + m_slist.append(st); + } + } + + ds << m_slist; + } + else if (command == "BIND") { + // Get desired Station Type from client + StationType st; + ds >> st; + + // Attempt to bind to station matching desired Service Type list... + m_stationID = -1; + + for (StationList::Iterator it(m_slist.begin()); it != m_slist.end(); ++it) { + if ((*it).services == st.services) { + m_stationID = (*it).id; + break; + } + } + + if (m_stationID < 0) { + ds << TQString("ERRUNAVAL"); + } + else { + // Update database + TQSqlRecord *buffer = m_databaseActivityCursor->primeInsert(); + buffer->setValue("station", m_stationID); + buffer->setValue("username", m_authenticatedUserName); + buffer->setValue("realmname", m_authenticatedRealmName); + buffer->setValue("logontime", TQDateTime::currentDateTime().toTime_t()); + m_databaseActivityCursor->insert(); + + ds << TQString("OK"); + } + } + else { + ds << "ERRINVCMD"; + } } tqApp->processEvents(); } @@ -108,6 +218,75 @@ printf("[RAJA DEBUG 500.0] Got command %s\n\r", command.ascii()); fflush(stdout) } +int AuthSocket::connectToDatabase() { + if (m_database) { + return -2; + } + + m_config->setGroup("Database"); + + m_database = TQSqlDatabase::addDatabase(m_config->readEntry("driver")); + m_database->setDatabaseName(m_config->readEntry("database")); + m_database->setUserName(m_config->readEntry("username")); + m_database->setPassword(m_config->readEntry("password")); + m_database->setHostName(m_config->readEntry("server")); + + if(!m_database->open()) { + printf("[ERROR] Failed to connect to control database on server '%s' [%s]\n\r", m_database->hostName().ascii(), m_database->lastError().text().ascii()); fflush(stdout); + delete m_database; + m_database = NULL; + return -1; + } + + if (!m_database->tables().contains("stations")) { + m_database->close(); + printf("[ERROR] Control database '%s' on '%s' does not contain the required 'stations' table\n\r", m_database->databaseName().ascii(), m_database->hostName().ascii()); fflush(stdout); + delete m_database; + m_database = NULL; + return -1; + } + + if (!m_database->tables().contains("services")) { + m_database->close(); + printf("[ERROR] Control database '%s' on '%s' does not contain the required 'services' table\n\r", m_database->databaseName().ascii(), m_database->hostName().ascii()); fflush(stdout); + delete m_database; + m_database = NULL; + return -1; + } + + if (!m_database->tables().contains("servicetypes")) { + m_database->close(); + printf("[ERROR] Control database '%s' on '%s' does not contain the required 'servicetypes' table\n\r", m_database->databaseName().ascii(), m_database->hostName().ascii()); fflush(stdout); + delete m_database; + m_database = NULL; + return -1; + } + + if (!m_database->tables().contains("permissions")) { + m_database->close(); + printf("[ERROR] Control database '%s' on '%s' does not contain the required 'permissions' table\n\r", m_database->databaseName().ascii(), m_database->hostName().ascii()); fflush(stdout); + delete m_database; + m_database = NULL; + return -1; + } + + if (!m_database->tables().contains("activity")) { + m_database->close(); + printf("[ERROR] Control database '%s' on '%s' does not contain the required 'activity' table\n\r", m_database->databaseName().ascii(), m_database->hostName().ascii()); fflush(stdout); + delete m_database; + m_database = NULL; + return -1; + } + + m_databaseStationsCursor = new TQSqlCursor("stations"); + m_databaseServicesCursor = new TQSqlCursor("services"); + m_databaseServiceTypesCursor = new TQSqlCursor("servicetypes"); + m_databasePermissionsCursor = new TQSqlCursor("permissions"); + m_databaseActivityCursor = new TQSqlCursor("activity"); + + return 0; +} + /* The AuthServer class handles new connections to the server. For every client that connects, it creates a new AuthSocket -- that instance is now @@ -116,14 +295,18 @@ printf("[RAJA DEBUG 500.0] Got command %s\n\r", command.ascii()); fflush(stdout) AuthServer::AuthServer(TQObject* parent) : TQServerSocket( 4004, 1, parent ) { + m_config = new KSimpleConfig("remotefpga_authserver.conf", false); + if ( !ok() ) { printf("[ERROR] Failed to bind to port 4004\n\r"); exit(1); } + + printf("[INFO] Server started on port 4004\n\r"); fflush(stdout); } AuthServer::~AuthServer() { - // + delete m_config; } void AuthServer::newConnection(int socket) { |