mirror of
https://github.com/outbackdingo/sysadm.git
synced 2026-01-27 02:20:17 +00:00
Clean up the server and bridge systems so that connections are now successful as needed.
This commit is contained in:
@@ -24,6 +24,7 @@ BridgeConnection::BridgeConnection(QWebSocket *sock, QString ID){
|
||||
connect(SOCKET, SIGNAL(binaryMessageReceived(const QByteArray&)), this, SLOT(EvaluateMessage(const QByteArray&)) );
|
||||
connect(SOCKET, SIGNAL(aboutToClose()), this, SLOT(SocketClosing()) );
|
||||
idletimer->start();
|
||||
requestIdentify();
|
||||
QTimer::singleShot(30000, this, SLOT(checkAuth()));
|
||||
}
|
||||
|
||||
@@ -116,6 +117,7 @@ void BridgeConnection::HandleAPIMessage(QString msg){
|
||||
// - Return messages first (check ID)
|
||||
QString id = JM.value("id").toString();
|
||||
if(id=="sysadm_bridge_request_ident"){
|
||||
qDebug() << "Got ident reply:" << JM;
|
||||
serverconn = (JM.value("args").toObject().value("type").toString() == "server");
|
||||
}else if("bridge_request_list_keys"){
|
||||
QStringList keys = JsonArrayToStringList(JM.value("args").toObject().value("md5_keys").toArray());
|
||||
@@ -134,7 +136,7 @@ void BridgeConnection::HandleAPIMessage(QString msg){
|
||||
namesp = JM.value("namespace").toString();
|
||||
out.insert("id", JM.value("id"));
|
||||
out.insert("namespace", namesp);
|
||||
out.insert("name","reponse");
|
||||
out.insert("name","response");
|
||||
QJsonValue outargs;
|
||||
//There is only a short list of API calls the bridge is capable of:
|
||||
if(namesp == "rpc" && name=="identify"){
|
||||
@@ -145,6 +147,7 @@ void BridgeConnection::HandleAPIMessage(QString msg){
|
||||
}else if(namesp == "rpc" && name=="auth_ssl"){
|
||||
if(!args.contains("encrypted_string")){
|
||||
//Stage 1 - send a random string to encrypt
|
||||
qDebug() << "Connection Auth Init:" << SockPeerIP;
|
||||
QString key = AUTHSYSTEM->GenerateEncCheckString();
|
||||
QJsonObject obj; obj.insert("test_string", key);
|
||||
outargs = obj;
|
||||
@@ -156,7 +159,7 @@ void BridgeConnection::HandleAPIMessage(QString msg){
|
||||
array.append(SockAuthToken);
|
||||
array.append(AUTHSYSTEM->checkAuthTimeoutSecs(SockAuthToken));
|
||||
outargs = array;
|
||||
qDebug() << "Connection Authorized:" << SockPeerIP;
|
||||
qDebug() << "Connection Authorized:" << SockPeerIP << "Type:" << (serverconn ? "server" : "client");
|
||||
QTimer::singleShot(10 ,this, SLOT(requestKeyList()) );
|
||||
}else{
|
||||
out.insert("name","error");
|
||||
@@ -232,6 +235,16 @@ void BridgeConnection::SslError(const QList<QSslError> &err){ //sslErrors() sign
|
||||
// ======================
|
||||
// PUBLIC SLOTS
|
||||
// ======================
|
||||
void BridgeConnection::requestIdentify(){
|
||||
QJsonObject obj;
|
||||
obj.insert("id","sysadm_bridge_request_ident");
|
||||
obj.insert("namespace","rpc");
|
||||
obj.insert("name","identify");
|
||||
obj.insert("args","");
|
||||
|
||||
SOCKET->sendTextMessage( QJsonDocument(obj).toJson(QJsonDocument::Compact) );
|
||||
}
|
||||
|
||||
void BridgeConnection::requestKeyList(){
|
||||
if(!AUTHSYSTEM->checkAuth(SockAuthToken)){ return; } //not authorized yet
|
||||
QJsonObject obj;
|
||||
|
||||
@@ -50,6 +50,7 @@ private slots:
|
||||
void SslError(const QList<QSslError>&); //sslErrors() signal
|
||||
|
||||
public slots:
|
||||
void requestIdentify();
|
||||
void requestKeyList();
|
||||
void announceIDAvailability(QStringList IDs);
|
||||
|
||||
|
||||
@@ -113,11 +113,13 @@ QString BridgeServer::generateID(QString name){
|
||||
// New Connection Signals
|
||||
void BridgeServer::NewSocketConnection(){
|
||||
BridgeConnection *sock = 0;
|
||||
qDebug() << "New incoming connection..";
|
||||
if(this->hasPendingConnections()){
|
||||
qDebug() << "New incoming connection..";
|
||||
QWebSocket *ws = this->nextPendingConnection();
|
||||
if(allowConnection(ws->peerAddress()) ){
|
||||
sock = new BridgeConnection( ws, generateID(ws->peerName()) );
|
||||
QString name = ws->peerName();
|
||||
if(name.isEmpty()){ name = ws->peerAddress().toString(); }
|
||||
sock = new BridgeConnection( ws, generateID(name) );
|
||||
}else{
|
||||
ws->abort();
|
||||
}
|
||||
@@ -125,7 +127,7 @@ void BridgeServer::NewSocketConnection(){
|
||||
if(sock==0){ return; } //no new connection
|
||||
//qDebug() << "New Socket Connection";
|
||||
connect(sock, SIGNAL(SocketClosed(QString)), this, SLOT(SocketClosed(QString)) );
|
||||
connect(sock, SIGNAL(SocketMessage(QString, QString)), this, SLOT(SendMessage(QString, QString)) );
|
||||
connect(sock, SIGNAL(SocketMessage(QString, QString)), this, SLOT(sendMessage(QString, QString)) );
|
||||
connect(sock, SIGNAL(keysChanged(QString, bool, QStringList)), this, SLOT(announceKeyChange(QString, bool, QStringList)) );
|
||||
OpenSockets << sock;
|
||||
}
|
||||
@@ -188,6 +190,7 @@ void BridgeServer::SocketClosed(QString ID){
|
||||
|
||||
// Connection Keys Changed
|
||||
void BridgeServer::announceKeyChange(QString ID, bool isServer, QStringList keys){
|
||||
qDebug() << "Key Change:" << ID << isServer << keys;
|
||||
for(int c = 0; c<OpenSockets.length(); c++){
|
||||
bool server = OpenSockets[c]->isServer();
|
||||
QStringList keys = OpenSockets[c]->validKeySums();
|
||||
@@ -199,6 +202,7 @@ void BridgeServer::announceKeyChange(QString ID, bool isServer, QStringList keys
|
||||
//compare keys to look for matches
|
||||
QStringList chkkeys = OpenSockets[i ]->validKeySums();
|
||||
chkkeys.removeDuplicates();
|
||||
qDebug() << "Known Keys for ID:" << OpenSockets[i]->ID() << chkkeys;
|
||||
chkkeys << keys;
|
||||
if(chkkeys.removeDuplicates() > 0){ IDs << OpenSockets[i]->ID(); }
|
||||
}
|
||||
|
||||
@@ -62,8 +62,17 @@ qDebug() << " \"blacklist/fails_to_block\" (integer): Number of times a syste
|
||||
|
||||
int main( int argc, char ** argv )
|
||||
{
|
||||
if(getuid() != 0){ CONFIG = new QSettings("sysadm","bridge"); SSLFILEDIR=CONFIG->fileName().section("/",0,-2); }
|
||||
else{ CONFIG = new QSettings("/var/db/sysadm-bridge.ini", QSettings::IniFormat); SSLFILEDIR="/usr/local/etc/sysadm"; }
|
||||
QString logdir;
|
||||
if(getuid() != 0){
|
||||
CONFIG = new QSettings("sysadm","bridge");
|
||||
SSLFILEDIR=CONFIG->fileName().section("/",0,-2);
|
||||
logdir = SSLFILEDIR;
|
||||
}
|
||||
else{
|
||||
CONFIG = new QSettings("/var/db/sysadm-bridge.ini", QSettings::IniFormat);
|
||||
SSLFILEDIR="/usr/local/etc/sysadm";
|
||||
logdir="/var/log";
|
||||
}
|
||||
qDebug() << "Using Config file:" << CONFIG->fileName();
|
||||
qDebug() << "SSL FILE DIR:" << SSLFILEDIR;
|
||||
//Evaluate input arguments
|
||||
@@ -147,7 +156,7 @@ int main( int argc, char ** argv )
|
||||
|
||||
//Setup the log file
|
||||
if(USELOG){
|
||||
logfile.setFileName(SSLFILEDIR+"/sysadm-bridge.log");
|
||||
logfile.setFileName(logdir+"/sysadm-bridge.log");
|
||||
qDebug() << "Log File:" << logfile.fileName();
|
||||
if(QFile::exists(logfile.fileName()+".old")){ QFile::remove(logfile.fileName()+".old"); }
|
||||
if(logfile.exists()){ QFile::rename(logfile.fileName(), logfile.fileName()+".old"); }
|
||||
|
||||
@@ -79,6 +79,8 @@ WebSocket::WebSocket(QString url, QString ID, AuthorizationManager *auth){
|
||||
connect(EVENTS, SIGNAL(NewEvent(EventWatcher::EVENT_TYPE, QJsonValue)), this, SLOT(EventUpdate(EventWatcher::EVENT_TYPE, QJsonValue)) );
|
||||
connect(this, SIGNAL(SendMessage(QString)), this, SLOT(sendReply(QString)) );
|
||||
connect(SOCKET, SIGNAL(connected()), this, SLOT(startBridgeAuth()) );
|
||||
//connect(SOCKET, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)) );
|
||||
connect(SOCKET, SIGNAL(sslErrors(const QList<QSslError>&)), this, SLOT(SslError(const QList<QSslError>&)) );
|
||||
//idletimer->start(); //do not idle out on a bridge connection
|
||||
/*QTimer::singleShot(30000, this, SLOT(checkAuth()));*/
|
||||
//Assemble the URL as needed
|
||||
@@ -86,7 +88,10 @@ WebSocket::WebSocket(QString url, QString ID, AuthorizationManager *auth){
|
||||
bool hasport = false;
|
||||
url.section(":",-1).toInt(&hasport); //check if the last piece of the url is a valid number
|
||||
if(!hasport){ url.append(":"+QString::number(BRIDGEPORTNUMBER)); }
|
||||
//Now setup/init the connection
|
||||
qDebug() << "Connecting to bridge:" << url;
|
||||
SOCKET->setSslConfiguration(QSslConfiguration::defaultConfiguration());
|
||||
//QTimer::singleShot(0,SOCKET, SLOT(ignoreSslErrors()) );
|
||||
SOCKET->open(QUrl(url));
|
||||
}
|
||||
|
||||
@@ -164,6 +169,7 @@ void WebSocket::EvaluateREST(QString msg){
|
||||
out.Header << "Content-Type: text/json; charset=utf-8";
|
||||
this->sendReply(out.assembleMessage());
|
||||
}else{
|
||||
qDebug() << "Got Message:" << IN.namesp << IN.name << IN.args << isBridge;
|
||||
if(IN.name.startsWith("auth") || (IN.namesp.toLower()=="rpc" && IN.name.toLower()=="identify") ){
|
||||
//Keep auth/pre-auth system requests in order
|
||||
EvaluateRequest(IN);
|
||||
@@ -362,6 +368,7 @@ if(out.in_struct.namesp.toLower() == "rpc"){
|
||||
}
|
||||
|
||||
void WebSocket::EvaluateResponse(const RestInputStruct& IN){
|
||||
qDebug() << "Evaluate Response:" << IN.id << IN.name << IN.args;
|
||||
if(!isBridge){ return; } //this is only valid for bridge connections
|
||||
if(IN.namesp=="events" && IN.name=="bridge"){
|
||||
QStringList bids = JsonArrayToStringList(IN.args.toObject().value("available_connections").toArray());
|
||||
@@ -538,14 +545,29 @@ void WebSocket::nowEncrypted(){
|
||||
}
|
||||
|
||||
void WebSocket::peerError(const QSslError&){ //peerVerifyError() signal
|
||||
//qDebug() << "Socket Peer Error:";
|
||||
qDebug() << "Socket Peer Error:";
|
||||
}
|
||||
|
||||
void WebSocket::SslError(const QList<QSslError> &err){ //sslErrors() signal
|
||||
LogManager::log(LogManager::HOST,"Connection SSL Errors ["+SockPeerIP+"]: "+err.length());
|
||||
QList<QSslError> ignored;
|
||||
for(int i=0; i< err.length(); i++){
|
||||
if(err[i].error()==QSslError::SelfSignedCertificate || err[i].error()==QSslError::HostNameMismatch ){
|
||||
//qDebug() << " - (IGNORED) " << err[i].errorString();
|
||||
ignored << err[i];
|
||||
}else{
|
||||
qWarning() << " - " << err[i].errorString();
|
||||
}
|
||||
}
|
||||
if(ignored.length() != err.length()){
|
||||
LogManager::log(LogManager::HOST,"Connection SSL Errors ["+SockPeerIP+"]: "+err.length());
|
||||
SOCKET->close(); //SSL errors - close the connection
|
||||
}else{
|
||||
SOCKET->ignoreSslErrors();
|
||||
}
|
||||
}
|
||||
|
||||
void WebSocket::startBridgeAuth(){
|
||||
qDebug() << "Init Bridge Auth...";
|
||||
QJsonObject obj;
|
||||
obj.insert("id", "server_to_bridge_auth");
|
||||
obj.insert("namespace","rpc");
|
||||
|
||||
@@ -101,8 +101,24 @@ int main( int argc, char ** argv )
|
||||
i=i+1;
|
||||
}else if(opt=="export_key"){
|
||||
//Export the public SSL cert used for establishing a connection with a bridge
|
||||
QString crt = ReadFile("/usr/local/etc/sysadm/ws_bridge.crt");
|
||||
qDebug() << crt.toLocal8Bit();
|
||||
QFile cfile("/usr/local/etc/sysadm/ws_bridge.crt");
|
||||
if( cfile.open(QIODevice::ReadOnly) ){
|
||||
QSslCertificate cert(&cfile);
|
||||
cfile.close();
|
||||
if(!cert.isNull()){
|
||||
if(i+1<argc){
|
||||
i++; QString filepath = argv[i];
|
||||
QFile outfile(filepath);
|
||||
outfile.open(QIODevice::WriteOnly | QIODevice::Truncate);
|
||||
outfile.write(cert.publicKey().toPem());
|
||||
outfile.close();
|
||||
qDebug() << "Public Key Saved to file:" << filepath;
|
||||
}else{
|
||||
//Output to std out instead
|
||||
qDebug() << cert.publicKey().toPem();
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
qDebug() << "Unknown option:" << argv[i];
|
||||
return 1;
|
||||
@@ -118,8 +134,13 @@ int main( int argc, char ** argv )
|
||||
bool ok = true;
|
||||
if(QFile::exists(key)){
|
||||
QFile file(key);
|
||||
if(file.open(QIODevice::ReadOnly)){ key = file.readAll(); file.close(); }
|
||||
else{ qDebug() << "Could not open file:" << file.fileName(); ok = false; }
|
||||
QByteArray pubkey;
|
||||
if(file.open(QIODevice::ReadOnly)){
|
||||
QSslKey sslkey( &file, QSsl::Rsa, QSsl::Pem, QSsl::PublicKey);
|
||||
if(!key.isNull()){ pubkey = sslkey.toPem(); }
|
||||
else{ qDebug() << "Invalid Key file:" << file.fileName(); ok = false; }
|
||||
file.close();
|
||||
}else{ qDebug() << "Could not open file:" << file.fileName(); ok = false; }
|
||||
}
|
||||
if(ok){ ok = AuthorizationManager::RegisterCertificateInternal(user, key, nickname, email); }
|
||||
if(ok){ qDebug() << "Key Added" << user << nickname; }
|
||||
|
||||
Reference in New Issue
Block a user