예제 #1
0
        /// <summary>
        /// Connect the management logic to OpenVPN
        /// </summary>
        protected bool connectLogic()
        {
            m_ovpnMLogic.reset();
            for (int i = 0; i < 8; ++i)
            {
                try
                {
                    System.Threading.Thread.Sleep(500); // TODO: 500
                    m_ovpnMLogic.connect();

                    return(true);
                }
                catch (System.Net.Sockets.SocketException ex)
                {
                    m_logs.logDebugLine(1, "Could not establish connection " +
                                        "to management interface:" + ex.Message);
                    if (i != 5)
                    {
                        m_logs.logDebugLine(1, "Trying again in a second");
                        System.Threading.Thread.Sleep(500);
                    }
                }
            }
            m_logs.logDebugLine(1, "Could not establish connection, abording");
            m_state = OVPNState.RUNNING;
            disconnect();

            while (m_state != OVPNState.STOPPED)
            {
                Thread.Sleep(200);
            }

            changeState(OVPNState.ERROR);
            return(false);
        }
예제 #2
0
        /// <summary>
        /// Start the OpenVPN binary.
        /// </summary>
        public void start()
        {
            m_logs.logDebugLine(1, "Starting OpenVPN");
            m_logs.logLine(OVPNLogEventArgs.LogType.MGNMT, "Starting OpenVPN...");

            m_process                     = new Process();
            m_process.StartInfo           = m_psi;
            m_process.Exited             += new EventHandler(this.exited_event);
            m_process.EnableRaisingEvents = true;

            try
            {
                m_process.Start();
            } catch (System.ComponentModel.Win32Exception) {
                m_logs.logLine(OVPNLogEventArgs.LogType.MGNMT, "Could not start OpenVPN");
                return;
            }

            m_logs.logDebugLine(1, "Started");
            m_logs.logLine(OVPNLogEventArgs.LogType.MGNMT, "OpenVPN is running");

            running = true;
        }
        /// <summary>
        /// a line was received, this method parses it and calls methods
        /// in the management logic.
        /// </summary>
        /// <param name="sender">ignored</param>
        /// <param name="e">information about the received line</param>
        /// <remarks>
        /// This method is not thread save!
        /// But there is no need to call it from more than one thread.
        /// Only the thread which holds the management connection calls this event.
        /// </remarks>
        private void oc_gotLine(object sender, GotLineEventArgs e)
        {
            // drop a line
            m_logs.logDebugLine(10, "Got: " + e.line);

            string s = e.line;

            // some lines start with a ">" (see link above)
            // they come asynchron and are parsed imediately
            if (s.StartsWith(">"))
            {
                string type = s.Substring(1, s.IndexOf(":") - 1);
                string msg  = s.Substring(type.Length + 2);

                string[] infos = null;
                AsyncEventDetail.EventType et = AsyncEventDetail.EventType.UNKNOWN;

                switch (type)
                {
                case "ECHO": et = AsyncEventDetail.EventType.ECHO; break;

                case "FATAL": et = AsyncEventDetail.EventType.FATAL; break;

                case "HOLD": et = AsyncEventDetail.EventType.HOLD; break;

                case "INFO": et = AsyncEventDetail.EventType.INFO; break;

                case "LOG": et = AsyncEventDetail.EventType.LOG; break;

                case "NEED-STR":
                    et = AsyncEventDetail.EventType.NEEDSTR;

                    string tmp = msg.Substring(msg.IndexOf('\'') + 1);
                    infos = new string[] { tmp.Substring(0, tmp.IndexOf('\'')) };
                    break;

                case "STATE":
                    et    = AsyncEventDetail.EventType.STATE;
                    infos = msg.Split(new char[] { ',' });
                    break;

                case "PASSWORD":
                    et = AsyncEventDetail.EventType.PASSWORD;
                    // Several messages format are possible
                    // * first is a request for a passwd
                    //   >PASSWORD:Need 'Auth' username/password
                    // or
                    //   >PASSWORD:Need 'Private Key' password
                    //
                    // * second is a notification
                    //   >PASSWORD:Verification Failed: 'Auth'
                    // or
                    //   >PASSWORD:Verification Failed: 'Private Key'

                    // Let's first determine the PASSWORD message type and thus format
                    string messType = msg.Substring(0, msg.IndexOf(' '));     // "Need" or "Verification"
                    if (messType.CompareTo("Need") == 0)
                    {
                        string tmp2         = msg.Substring(msg.IndexOf('\'') + 1);
                        string loginProfile = tmp2.Substring(0, tmp2.IndexOf('\''));   // 'Auth' or 'Private Key' or ...
                        string loginInfo    = tmp2.Substring(tmp2.IndexOf('\'') + 2);  // "password" or "username/password"
                        infos = new string[] { loginProfile, loginInfo, messType };
                    }
                    else if (messType.CompareTo("Verification") == 0)
                    {
                        string verifMsg = msg.Substring(0, msg.IndexOf(':'));     // "Verification Failed"
                        if (verifMsg.CompareTo("Verification Failed") == 0)
                        {
                            string tmp2         = msg.Substring(msg.IndexOf('\'') + 1);
                            string loginProfile = tmp2.Substring(0, tmp2.IndexOf('\''));     // 'Auth' or 'Private Key' or ...
                            infos = new string[] { loginProfile, null, verifMsg };
                        }
                    }
                    break;
                }

                if (et != AsyncEventDetail.EventType.UNKNOWN)
                {
                    m_ol.got_asyncEvent(new AsyncEventDetail(et, msg, infos));
                    return;
                }
            }

            m_received.Append(s + Environment.NewLine);
            s = m_received.ToString();

            if (s.StartsWith("SUCCESS: ") || s.StartsWith("ERROR: ") ||
                s.StartsWith(">") || s.EndsWith("END" + Environment.NewLine))
            {
                m_received.Remove(0, m_received.Length);
                m_ol.cb_syncEvent(s);
            }
        }
        /// <summary>
        /// Connects to the management interface.
        /// </summary>
        public void connect()
        {
            m_logs.logLine(OVPNLogEventArgs.LogType.MGNMT, "Connecting to management interface");
            m_logs.logDebugLine(1, "Connecting to management interface");

            try
            {
                m_tcpC.Connect(m_host, m_port);
            }
            catch (SocketException e)
            {
                m_logs.logDebugLine(1, "Connection failed: " + e.Message);
                throw; // new ApplicationException("Could not connect to socket: " + e.Message);
            }

            m_sread       = new StreamReader(m_tcpC.GetStream());
            m_swrite      = new StreamWriter(m_tcpC.GetStream());
            m_reader      = new Thread(new ThreadStart(readerThread));
            m_reader.Name = "management interface reader thread";
            m_reader.Start();
            m_connected = true;
        }
예제 #5
0
        /// <summary>
        /// We got a synchronous message.
        /// </summary>
        /// <param name="msg">The message</param>
        public void cb_syncEvent(string msg)
        {
            // the reaction depends on what we are waiting for
            switch (m_state)
            {
            // the number of SmartCards
            case WaitState.PKCS11_GET_COUNT:
                m_pkcs11count = m_ovpnMParser.getPKCS11IDCount(msg);

                if (m_pkcs11count == -1)
                {
                    m_logs.logLine(OVPNLogEventArgs.LogType.MGNMT,
                                   "Could not determine the number of pkcs11-ids:\"" +
                                   msg + "\"");
                    releaseLock();
                }

                else if (m_pkcs11count == 0)
                {
                    m_logs.logLine(OVPNLogEventArgs.LogType.MGNMT,
                                   "No pkcs11-ids were found");

                    int id = m_ovpn.getKeyID(new List <PKCS11Detail>());
                    if (id == OVPNNeedCardIDEventArgs.RETRY)
                    {
                        m_ovpnComm.send("pkcs11-id-count");
                    }
                    else
                    {
                        releaseLock();
                    }
                }
                else
                {
                    m_logs.logLine(OVPNLogEventArgs.LogType.MGNMT,
                                   "Got " + m_pkcs11count + " PKCS11-IDs");
                    m_pkcs11details.Clear();
                    releaseLock();

                    setLock(WaitState.PKCS11_GET_KEYS);
                    m_ovpnComm.send("pkcs11-id-get 0");
                }

                break;

            case WaitState.PKCS11_GET_KEYS:
                PKCS11Detail d = m_ovpnMParser.getPKCS11ID(msg);

                if (d != null)
                {
                    m_pkcs11details.Add(d);

                    if (d.nr < m_pkcs11count - 1)
                    {
                        m_ovpnComm.send("pkcs11-id-get " + (d.nr + 1));
                    }

                    else
                    {
                        releaseLock();

                        int kid = m_ovpn.getKeyID(m_pkcs11details);

                        if (kid == OVPNNeedCardIDEventArgs.RETRY)
                        {
                            setLock(WaitState.PKCS11_GET_COUNT);
                            m_ovpnComm.send("pkcs11-id-count");
                        }
                        else if (kid != OVPNNeedCardIDEventArgs.NONE)
                        {
                            m_ovpnComm.send("needstr 'pkcs11-id-request' '" +
                                            m_pkcs11details[kid].id + "'");
                        }
                    }
                }

                // error in parsing
                else
                {
                    m_logs.logDebugLine(1,
                                        "Error while parsing pkcs11-id-get: \"" +
                                        msg + "\"");

                    releaseLock();
                }
                break;

            // logging was turned on, wait for log lines
            case WaitState.LOG_ON_ALL_1:
                setLock(WaitState.LOG_ON_ALL_2,true);
                break;

            // logging was turned on
            case WaitState.LOG_ON:
            case WaitState.LOG_ON_ALL_2:
                releaseLock();

                string[] m = msg.Split("\n".ToCharArray());
                for (int i = 0; i < m.GetUpperBound(0) - 1; ++i)
                {
                    addLog(m[i]);
                }

                setLock(WaitState.STATE);
                m_ovpnComm.send("state on");
                break;

            // "state" was set
            case WaitState.STATE:
                releaseLock();

                if (m_releaselock)
                {
                    setLock(WaitState.HOLD_RELEASE);
                    m_ovpnComm.send("hold release");
                    m_releaselock = false;
                }

                break;

            // hold relese was executed
            case WaitState.HOLD_RELEASE:
                releaseLock();
                break;

            // we sent a signal
            case WaitState.SIGNAL:
                releaseLock();
                break;

            // something else happened (this should not happen)
            // we release the lock
            default:
                releaseLock();
                break;
            }
        }