/*************************************************************************** * Copyright (C) 2006 by Michael Kaufmann * * michael@enlighter.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifndef OPENVPNMANAGER_H #define OPENVPNMANAGER_H #include "authmanager.h" #include "bufferedsocket.h" #include #include #include /** @author Michael Kaufmann */ class openVPNManager : public QObject { Q_OBJECT public: // These are the OpenVPN states (taken from the openvpn homepage) // // CONNECTING -- OpenVPN's initial state. // WAIT -- (Client only) Waiting for initial response from server. // AUTH -- (Client only) Authenticating with server. // GET_CONFIG -- (Client only) Downloading configuration options from server. // ASSIGN_IP -- Assigning IP address to virtual network // interface. // ADD_ROUTES -- Adding routes to system. // CONNECTED -- Initialization Sequence Completed. // RECONNECTING -- A restart has occurred. // EXITING -- A graceful exit is in progress. // DISCONNECTED -- IS NOT AN OPENVPN STATUS: it is set, when openVPN waits for a hold release, password. // UNKNOWN -- IS NOT AN OPENVPN STATUS: it is set, when kovpn has no access to the OpenVPN daemon. enum states { EXITING = 1, DISCONNECTED, CONNECTING, WAIT, AUTH, GET_CONFIG, ASSIGN_IP, ADD_ROUTES, RECONNECTING, CONNECTED, FAILED, UNKNOWN }; struct tStatus { states state; QString localIP; QString remoteIP; QString remoteName; unsigned int uptime; }; /* This are all currently handled non-realtime notifications that I can handle. If m_ovpnLastRequest = STATE, the next non-realtime message is passed over to a method to handle non-realtime STATE messages. */ enum requests { MISC = 0, STATE, STATUS, LOG, ECHO, AUTHENTICATE, PRIVATEKEY, MIPASSWORD, DIRECT }; openVPNManager( const QString & id, const QString & host, const QString & port, const bool saveMIPassword, const bool saveAccount, const bool savePassphrase, const bool reconnect, const bool autoconnect, const bool disconnectOnExit ); ~openVPNManager(); /* Reconfigure this Manager */ // void setId( const QString & id ); QString id(); void setHost( const QString & host ); QString host(); void setPort( const QString & port ); QString port(); void setSaveMIPassword( const bool saveMIPassword ); bool saveMIPassword(); void setSaveAccount( const bool saveAccount ); bool saveAccount(); void setSavePassphrase( const bool savePassphrase ); bool savePassphrase(); void setReconnect( const bool reconnect ); bool reconnect(); void setAutoconnect( const bool autoconnect ); bool autoconnect(); void setDisconnectOnExit( const bool disconnectOnExit ); bool disconnectOnExit(); bool startUptimeCounter(); bool stopUptimeCounter(); /* Get Informations about OpenVPN's status */ // states status(); /* Returns the status of the OpenVPN connection */ tStatus status(); /* Returns the status of the OpenVPN connection */ QString ip(); /* Returns die IP in Format X.X.X.X */ int uptime(); /* Returns the uptime in seconds */ states toStatus( QString ); public slots: void connect(); void disconnect(); void directCommand( const QString & ); // void reconnect(); signals: void message( const QString &, const QString &, openVPNManager::requests ); void message( bool & yesno, const QString & title, const QString & message ); void error( const QString & ); void signalSocketConnected(); /* emits whenever a connection to the openvpn's management interface has been established. This is when the management interface answers: >INFO:OpenVPN Management Interface Version 1 -- type 'help' for more info */ /* Signals for OpenVPN State change notifications. */ void signalOvpnHold( QString ); /* emits whenever a HOLD notification is received */ void signalOvpnState( QString ); /* emits whenever the openvpn state has been changed. */ void signalOvpnLog( QString ); /* emits whenever openvpn produces log messages. */ void signalOvpnPassword( QString ); /* emits whenever a PASSWORD notification is received */ void signalOvpnAuthRequest(); /* emits whenever openvpn requests a username and/or password */ /* Signals for internal uptime counter */ void signalOvpnConnected(); void signalOvpnDisconnected(); /* Signals to inform GUI */ void signalOvpnReady( const QString & ); /* OpenVPN is ready to receive commands. */ void signalOvpnNotReady( const QString & ); /* OpenVPN is not ready to receive commands. */ void signalOvpnPreReady( const QString & ); /* OpenVPN is not nearly ready to receive commands. Management Interface PW is still missing */ void signalOvpnStatusChanged( const QString &, openVPNManager::states ); void signalOvpnStatusChanged( const QString &, openVPNManager::tStatus ); void signalOvpnServerChanged( const QString &, const QString & ); void signalOvpnServerChanged( const QString &, openVPNManager::tStatus ); void signalOvpnIPChanged( const QString &, const QString & ); void signalOvpnIPChanged( const QString &, openVPNManager::tStatus ); void signalOvpnUptimeChanged( const QString &, const int & ); void signalOvpnUptimeChanged( const QString &, openVPNManager::tStatus ); void signalCommandToProcess(); /* Used only internally. Writing commands uses a writing queue. This indicates that this queue is not empty */ protected slots: // void ovpnActivate(); /* Sends a "hold release" command to openvpn */ // void ovpnLogin(); /* Sends login data to openvpn */ // void ovpnLogout(); /* Sends logout command to openvpn */ // bool reconnect(); /* For GUI, that it can ask if we try to reconnect or not. */ // QString id(); void socketReadyRead(); /* Ready to ready from the management interface */ void socketGotError( int ); /* socket to the management interface has an error */ void socketStateChanged( int ); void socketWrite(); /* Sends a command to openvpn. Get's commands from writeQueue */ bool socketConnect(); /* connects to the management interface */ void socketDisconnect(); /* disconnectes from the management interface */ void ovpnTimer(); /* signals the GUI's to update its uptime display */ protected: void debug( const QString & method, const QString & message = "I was called" ); void ovpnInit(); /* Initializes the management interface */ void ovpnHold( QString ); /* Manages the HOLD notifications */ void ovpnState( QString ); /* OpenVPN State Changes */ void ovpnLog( QString ); /* OpenVPN LOG messages */ void ovpnPassword( QString ); /* Manages the PASSWORD notifications */ void ovpnFatal( QString ); void ovpnNeedok( QString ); void ovpnConnect(); /* connect to the remote openVPN server */ void ovpnForceConnect(); /* just for compatiblity reasons with KAction */ void ovpnDisconnect(); /* disconnect from the remote openVPN server */ void ovpnReconnect(); /* disconnect from the remote openVPN server */ void ovpnAuthenticate( const QString & type, const QString & username, const QString & password ); /* Sends Auth data to openvpn */ void ovpnPKPassphrase( const QString & type, const QString & passphrase ); /* Sends the private key passphrase to openvpn */ void ovpnMIPassword( const QString & password ); /* Send the password for the management interface to openvpn */ void ovpnStartTimer(); void ovpnStopTimer(); /* Don't know if I need it */ private: /* Configuration variables */ QString mId; /* this identifyes the connection */ QString mHost; QString mPort; bool mSaveAccount; bool mSaveMIPassword; bool mSavePassphrase; bool mReconnect; bool mAutoconnect; bool mDisconnectOnExit; /* Configuration variables end. */ void command( QString command, requests type = MISC ); bufferedSocket * mSocket; // Waren da () ???? bool mForce; /* force sending hold release even if openvpn doesn'n requests for it at the moment. Of course it has had to request it sometimes before to result in a connection to the openvpn server. It is needed because otherwise after a Disconnect command from the GUI it would automatically reconnect and that's surely not what the user expects. */ bool mWaitingForHoldRelease; /* OpenVPN want's a hold release to connect */ bool mWaitingForAuth; /* OpenVPN want's a username/password pair to connect */ bool mWaitingForPass; /* OpenVPN want's a private key passphrase to connect */ bool mWaitingForMIPass; /* OpenVPN's management interface wants a access password beforce I can controll it */ bool mMIAuthFailed; /* This must be global, because it cannot be decided in the same method. */ bool mConnectionWanted; /* If an connection was requested by the user in any way. Is mainly needed for correct Autoconnect/Reconnect in ovpnHold() */ bool mDisconnectForced; /* If user explicitely requested a disconnection. Is mainly needed for ovpnHold() */ bool mInitialStatusReported; /* Was the status reported to the GUI at least one single time? */ /* Configuration variables */ // QString c_host, c_port; /* Host and port, where the openVPN management interface runs. */ // bool c_saveManagementPassword; /* Save management password in kwallet */ // bool c_autoConnect; /* automatically connect if possible? */ // bool c_saveOvpnPassword; /* Save Username/Password in KWallet */ /* Configuration variables end */ /* Uptime GUI notifications & OpenVPN Status */ QTimer * mOvpnTimer; /* is used to emit a signal to update GUI's uptime display */ QDateTime * mOvpnConnectionStart; /* Stores the time when the connection has been established. */ requests mOvpnLastRequest; /* OpenVPN Status information */ tStatus mStatus; /* Status of the openVPN connection */ tStatus mLastStatus; /* Last status of openVPN */ // QString mRemoteCN; /* Common Name of the remote OpenVPN server. */ // QString mIP; /* IP address of the local OpenVPn tun/tap device */ // int mUptime; KNetwork::KClientSocketBase::SocketState mSocketStatus; struct job { requests type; QString command; }; /* Sending commands to openVPN works so: 1. enqueue the command with the type into the writeQueue. openVPNManager::command(, ); 2. the signal signalCommandToProcess() is emitted 3. the slot socketWrite() is called which "executes" the command and enqueues the command's type into readQueue 4. slotSocketReadReady reads the output and as soon as it is finished, it will call the appropriate method according to the type in readQueue. NO ISSUES: Real-time notifications, END terminated notifications. ISSUES: not END terminated notifications (single-line notifications). */ QPtrQueue mWriteQueue; QPtrQueue mReadQueue; /* If connection is lost, use this timer to try to reconnect periodically */ QTimer * mSocketTimer; authManager * mAuthManager; // QString m_ressource; // Identifyer of the connection // QString m_commonName; // Common name of the remote openVPN server static int mCounter; /* The overall amount of instances */ int mInstance; /* The instance number. Used for reading the config. */ unsigned int mInterval; /* Interval between reconnection to the management interface */ unsigned int mUptimeRequestCounter; /* Count how much modules want an uptime change to be emitted. if 0 then stop */ }; #endif