示例#1
0
 /// <summary>
 /// ユーザー名を決定して返す
 /// </summary>
 /// <param name="user"></param>
 /// <param name="credential"></param>
 /// <returns></returns>
 protected string GetUserName(string user, PSCredential credential, SshSession session)
 {
     if (credential != null)
     {
         return(credential.UserName);
     }
     if (string.IsNullOrEmpty(user) && (session?.IsUserEmpty() ?? true))
     {
         Console.Write("User: ");
         user = Console.ReadLine();
     }
     return(user);
 }
 private SshTunnelingHostListService(
     LocalPortForwarding localPortForwarding,
     IPEndPoint host,
     NetworkCredential networkCredential,
     HttpHostListService http,
     SshSession session)
 {
     _localPortForwarding = localPortForwarding;
     _host = host;
     _networkCredential = networkCredential;
     _http    = http;
     _session = session;
 }
示例#3
0
        protected override void ProcessRecord()
        {
            var session = new SshSession()
            {
                Server              = this.Server,
                Port                = this.Port,
                User                = this.User,
                Password            = this.Password,
                KeyboardInteractive = this.KeyboardInteractive,
            };

            WriteObject(session, true);
        }
示例#4
0
        //---------------------------------------------------------------------
        // Helper methods.
        //---------------------------------------------------------------------

        protected static SshSession CreateSession()
        {
            var session = new SshSession();

            session.SetTraceHandler(
                LIBSSH2_TRACE.SOCKET | LIBSSH2_TRACE.ERROR | LIBSSH2_TRACE.CONN |
                LIBSSH2_TRACE.AUTH | LIBSSH2_TRACE.KEX,
                Console.WriteLine);

            session.Timeout = TimeSpan.FromSeconds(5);

            return(session);
        }
示例#5
0
        public static void ThrowsNativeExceptionWithError(
            SshSession session,
            LIBSSH2_ERROR expected,
            Action action)
        {
            try
            {
                action();
                Assert.Fail("Expected SshNativeException with error " + expected);
            }
            catch (Exception e) when(!(e is AssertionException))
            {
                Assert.IsInstanceOf(typeof(SshNativeException), e.Unwrap());
                Assert.AreEqual(expected, ((SshNativeException)e.Unwrap()).ErrorCode);

                if (session != null)
                {
                    Assert.IsTrue(session.LastError == LIBSSH2_ERROR.NONE ||
                                  session.LastError == expected);
                }
            }
        }
示例#6
0
        private void WorkerThreadProc()
        {
            //
            // NB. libssh2 has limited support for multi-threading and in general,
            // it's best to use a libssh2 session from a single thread only.
            // Therefore, all libssh2 operations are performed by this one thead.
            //

            using (SshTraceSources.Default.TraceMethod().WithoutParameters())
            {
                try
                {
                    using (var session = new SshSession())
                    {
                        session.SetTraceHandler(
                            LIBSSH2_TRACE.SOCKET | LIBSSH2_TRACE.ERROR | LIBSSH2_TRACE.CONN |
                            LIBSSH2_TRACE.AUTH | LIBSSH2_TRACE.KEX,
                            SshTraceSources.Default.TraceVerbose);


                        if (!string.IsNullOrEmpty(this.Banner))
                        {
                            session.SetLocalBanner(this.Banner);
                        }

                        session.Timeout = this.ConnectionTimeout;

                        //
                        // Open connection and perform handshake using blocking I/O.
                        //
                        // TODO: Configure algorithms.
                        //
                        using (var connectedSession = session.Connect(this.endpoint))
                            using (var authenticatedSession = connectedSession.Authenticate(
                                       this.username,
                                       this.key,
                                       this.OnKeyboardInteractivePromptCallback))
                                using (var channel = CreateChannel(authenticatedSession))
                                {
                                    //
                                    // With the channel established, switch to non-blocking I/O.
                                    // Use a disposable scope to make sure that tearing down the
                                    // connection is done using blocking I/O again.
                                    //
                                    using (session.AsNonBlocking())
                                        using (var readyToReceive = UnsafeNativeMethods.WSACreateEvent())
                                        {
                                            //
                                            // Create an event that is signalled whenever there is data
                                            // available to read on the socket.
                                            //
                                            // NB. This is a manual-reset event that must be reset by
                                            // calling WSAEnumNetworkEvents.
                                            //

                                            if (UnsafeNativeMethods.WSAEventSelect(
                                                    connectedSession.Socket.Handle,
                                                    readyToReceive,
                                                    UnsafeNativeMethods.FD_READ) != 0)
                                            {
                                                throw new Win32Exception(
                                                          UnsafeNativeMethods.WSAGetLastError(),
                                                          "WSAEventSelect failed");
                                            }

                                            // TODO: Check host keys.

                                            //
                                            // Looks good so far, consider the connection successful.
                                            //
                                            OnConnected();

                                            //
                                            // Set up keepalives. Because we use non-blocking I/O, we have to
                                            // send keepalives by ourselves.
                                            //
                                            // NB. This method must not be called before the handshake has completed.
                                            //
                                            session.ConfigureKeepAlive(false, this.KeepAliveInterval);

                                            var waitHandles = new[]
                                            {
                                                readyToReceive.DangerousGetHandle(),
                                                this.readyToSend.DangerousGetHandle()
                                            };

                                            while (!this.workerCancellationSource.IsCancellationRequested)
                                            {
                                                var currentOperation = Operation.Receiving | Operation.Sending;

                                                try
                                                {
                                                    //
                                                    // In each iteration, wait for
                                                    // (data received on socket) OR (user data to send)
                                                    //
                                                    // NB. The timeout should not be lower than approx.
                                                    // one second, otherwise we spend too much time calling
                                                    // libssh2's keepalive function, which causes the terminal
                                                    // to become sluggish.
                                                    //

                                                    var waitResult = UnsafeNativeMethods.WSAWaitForMultipleEvents(
                                                        (uint)waitHandles.Length,
                                                        waitHandles,
                                                        false,
                                                        (uint)this.SocketWaitInterval.TotalMilliseconds,
                                                        false);

                                                    if (waitResult == UnsafeNativeMethods.WSA_WAIT_EVENT_0)
                                                    {
                                                        //
                                                        // Socket has data available.
                                                        //
                                                        currentOperation = Operation.Receiving;

                                                        //
                                                        // Reset the WSA event.
                                                        //
                                                        var wsaEvents = new UnsafeNativeMethods.WSANETWORKEVENTS()
                                                        {
                                                            iErrorCode = new int[10]
                                                        };

                                                        if (UnsafeNativeMethods.WSAEnumNetworkEvents(
                                                                connectedSession.Socket.Handle,
                                                                readyToReceive,
                                                                ref wsaEvents) != 0)
                                                        {
                                                            throw new Win32Exception(
                                                                      UnsafeNativeMethods.WSAGetLastError(),
                                                                      "WSAEnumNetworkEvents failed");
                                                        }

                                                        //
                                                        // Perform whatever receiving operation we need to do.
                                                        //

                                                        Receive(channel);
                                                    }
                                                    else if (waitResult == UnsafeNativeMethods.WSA_WAIT_EVENT_0 + 1)
                                                    {
                                                        //
                                                        // User has data to send. Perform whatever send operation
                                                        // we need to do.
                                                        //
                                                        currentOperation = Operation.Sending;
                                                        Send(channel);
                                                    }
                                                    else if (waitResult == UnsafeNativeMethods.WSA_WAIT_TIMEOUT)
                                                    {
                                                        //
                                                        // Channel is idle - use the opportunity to send a
                                                        // keepalive. Libssh2 will ignore the call if no
                                                        // keepalive is due yet.
                                                        //
                                                        session.KeepAlive();
                                                    }
                                                    else if (waitResult == UnsafeNativeMethods.WSA_WAIT_FAILED)
                                                    {
                                                        throw new Win32Exception(
                                                                  UnsafeNativeMethods.WSAGetLastError(),
                                                                  "WSAWaitForMultipleEvents failed");
                                                    }
                                                }
                                                catch (SshNativeException e) when(e.ErrorCode == LIBSSH2_ERROR.EAGAIN)
                                                {
                                                    // Retry operation.
                                                }
                                                catch (Exception e)
                                                {
                                                    SshTraceSources.Default.TraceError(
                                                        "Socket I/O failed for {0}: {1}",
                                                        Thread.CurrentThread.Name,
                                                        e);

                                                    if ((currentOperation & Operation.Sending) != 0)
                                                    {
                                                        this.OnSendError(e);
                                                    }
                                                    else
                                                    {
                                                        // Consider it a receive error.
                                                        this.OnReceiveError(e);
                                                    }

                                                    // Bail out.
                                                    return;
                                                }
                                            } // while
                                        }// nonblocking

                                    try
                                    {
                                        channel.Close();
                                    }
                                    catch (Exception e)
                                    {
                                        // NB. This is non-fatal - we're tearing down the
                                        // connection anyway..

                                        SshTraceSources.Default.TraceError(
                                            "Closing connection failed for {0}: {1}",
                                            Thread.CurrentThread.Name,
                                            e);
                                    }
                                }
                    }
                }
                catch (Exception e)
                {
                    SshTraceSources.Default.TraceError(
                        "Connection failed for {0}: {1}",
                        Thread.CurrentThread.Name,
                        e);

                    OnConnectionError(e);
                }
            }
        }
示例#7
0
 /// <summary>
 /// パスワードを決定して返す。
 /// </summary>
 /// <param name="password"></param>
 /// <param name="credential"></param>
 /// <param name="passwordFile"></param>
 /// <returns></returns>
 protected string GetPassword(string password, PSCredential credential, string passwordFile, SshSession session)
 {
     if (credential != null)
     {
         //  Credentialからパスワード読み取り
         return(System.Runtime.InteropServices.Marshal.PtrToStringUni(
                    System.Runtime.InteropServices.Marshal.SecureStringToGlobalAllocUnicode(credential.Password)));
     }
     else if (!string.IsNullOrEmpty(passwordFile) && File.Exists(passwordFile))
     {
         //  PasswordFileからパスワード読み取り
         try
         {
             //  ===========================================
             //  $cred = Get-Credential
             //  $cred.Password | ConvertFrom-SecureString | Set-Content .\pwoutput.txt
             //  ===========================================
             //  等で、PowerShellで暗号化したパスワードファイルをした場合
             var res = InvokeCommand.InvokeScript(
                 SessionState,
                 InvokeCommand.NewScriptBlock(
                     "[System.Runtime.InteropServices.Marshal]::PtrToStringBSTR(" +
                     "[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR(" +
                     $"(Get-Content \"{passwordFile}\" | ConvertTo-SecureString)))"));
             if (res != null && res.Count > 0)
             {
                 return(res[0].ToString());
             }
         }
         catch
         {
             //  PowerShellで暗号化したパスワードファイルの読み込みに失敗した場合、平文テキストとして読み込み
             //  複数行の場合、最初の1行のみをパスワードとして判断
             using (var sr = new StreamReader(passwordFile, new UTF8Encoding(false)))
             {
                 return(sr.ReadLine());
             }
         }
     }
     else if (string.IsNullOrEmpty(password) && (session?.IsPasswordEmpty() ?? true))
     {
         //  Password, PasswordFile, Credentialの全部が空の場合
         return(ReadPassword());
     }
     return(password);
 }
        public void WhenRequriedVersionIsLower_ThenVersionReturnsXxx()
        {
            var version = SshSession.GetVersion(new Version(1, 0, 0));

            Assert.IsNotNull(version);
        }
        public void WhenRequriedVersionIsHigher_ThenVersionReturnsNull()
        {
            var version = SshSession.GetVersion(new Version(0xCC, 0xBB, 0xAA));

            Assert.IsNull(version);
        }