Quantcast
Channel: sshnet Discussions Rss Feed
Viewing all articles
Browse latest Browse all 1729

New Post: Pageant integration?

$
0
0
I had to upload the old patch files as a new patchid (Which will most certainly be declined). It is available here. The modification for Windows 7 to pageantprotocol.cs follows:
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Linq;
using System.Net;
using System.Text;
using Renci.SshNet.Common;
using System.Security.AccessControl;

namespace Renci.SshNet.Pageant
{
   public class PageantProtocol:IAgentProtocol
    {

        #region  Constants

        private const int WM_COPYDATA = 0x004A;

        private const int AGENT_COPYDATA_ID = unchecked((int)0x804e50ba);

        private const int AGENT_MAX_MSGLEN = 8192;

        public const byte SSH2_AGENTC_REQUEST_IDENTITIES = 11;

        public const byte SSH2_AGENT_IDENTITIES_ANSWER = 12;

        public const byte SSH2_AGENTC_SIGN_REQUEST = 13;

        public const byte SSH2_AGENT_SIGN_RESPONSE = 14;

        #endregion


       public static bool IsRunning
       {
           get
           {
               var hWnd = NativeMethods.FindWindow("Pageant", "Pageant");

               return hWnd != IntPtr.Zero;
           }
       }



        public PageantProtocol()
        {
            var hWnd = NativeMethods.FindWindow("Pageant", "Pageant");

            if (hWnd == IntPtr.Zero)
            {
                throw new SshException("Pageant not running");
            }
            
        }


        #region Implementation of IAgentProtocol

        IEnumerable<IdentityReference> IAgentProtocol.GetIdentities()
        {
            var hWnd = NativeMethods.FindWindow("Pageant", "Pageant");

            if (hWnd == IntPtr.Zero)
            {
                yield break;
            }

            string mmFileName = Path.GetRandomFileName();
            
            using (var mmFile = MemoryMappedFile.CreateNew(
                mmFileName,
                AGENT_MAX_MSGLEN))
            {
                var security = mmFile.GetAccessControl();
                security.SetOwner(System.Security.Principal.WindowsIdentity.GetCurrent().User);
                mmFile.SetAccessControl(security);

                using (var accessor = mmFile.CreateViewAccessor())
                {
                    accessor.Write(0, IPAddress.NetworkToHostOrder(AGENT_MAX_MSGLEN - 4));
                    accessor.Write(4, SSH2_AGENTC_REQUEST_IDENTITIES);

                    var copy = new COPYDATASTRUCT(AGENT_COPYDATA_ID, mmFileName);

                    if (NativeMethods.SendMessage(hWnd, WM_COPYDATA, IntPtr.Zero, ref copy) == IntPtr.Zero)
                    {
                        accessor.Dispose();
                        mmFile.Dispose();
                        File.Delete(mmFileName);
                        yield break;
                    }

                    if (accessor.ReadByte(4) != SSH2_AGENT_IDENTITIES_ANSWER)
                    {
                        accessor.Dispose();
                        mmFile.Dispose();
                        File.Delete(mmFileName);
                        yield break;
                    }

                    int numberOfIdentities = IPAddress.HostToNetworkOrder(accessor.ReadInt32(5));

                    if (numberOfIdentities == 0)
                    {
                        accessor.Dispose();
                        mmFile.Dispose();
                        File.Delete(mmFileName);
                        yield break;
                    }

                    int position = 9;
                    for (int i = 0; i < numberOfIdentities; i++)
                    {
                        int blobSize = IPAddress.HostToNetworkOrder(accessor.ReadInt32(position));
                        position += 4;

                        var blob = new byte[blobSize];

                        accessor.ReadArray(position, blob, 0, blobSize);
                        position += blobSize;
                        int commnetLenght = IPAddress.HostToNetworkOrder(accessor.ReadInt32(position));
                        position += 4;
                        var commentChars = new byte[commnetLenght];
                        accessor.ReadArray(position, commentChars, 0, commnetLenght);
                        position += commnetLenght;

                        string comment = Encoding.ASCII.GetString(commentChars);
                        string type = Encoding.ASCII.GetString(blob, 4, 7);// needs more testing kind of hack

                        accessor.Dispose();
                        mmFile.Dispose();
                        File.Delete(mmFileName);

                        yield return new IdentityReference(type,blob,comment);

                    }

                    accessor.Dispose();
                    mmFile.Dispose();
                    File.Delete(mmFileName);
                }
            }
        }
        
        byte[] IAgentProtocol.SignData(IdentityReference identity, byte[] data)
        {
            var hWnd = NativeMethods.FindWindow("Pageant", "Pageant");

            if (hWnd == IntPtr.Zero)
            {
                return new byte[0];
            }

            string mmFileName = Path.GetRandomFileName();

            using (var mmFile = MemoryMappedFile.CreateNew(mmFileName,AGENT_MAX_MSGLEN))
            {
                using (var accessor = mmFile.CreateViewAccessor())
                {
                    var security = mmFile.GetAccessControl();
                    security.SetOwner(System.Security.Principal.WindowsIdentity.GetCurrent().User);
                    mmFile.SetAccessControl(security);

                    accessor.Write(0, IPAddress.NetworkToHostOrder(AGENT_MAX_MSGLEN - 4));
                    accessor.Write(4, SSH2_AGENTC_SIGN_REQUEST);
                    accessor.Write(5, IPAddress.NetworkToHostOrder(identity.Blob.Length));
                    accessor.WriteArray(9, identity.Blob, 0, identity.Blob.Length);
                    accessor.Write(9 + identity.Blob.Length, IPAddress.NetworkToHostOrder(data.Length));
                    accessor.WriteArray(13 + identity.Blob.Length, data, 0, data.Length);

                    var copy = new COPYDATASTRUCT(AGENT_COPYDATA_ID, mmFileName);

                    if (NativeMethods.SendMessage(hWnd, WM_COPYDATA, IntPtr.Zero, ref copy) == IntPtr.Zero)
                    {
                        accessor.Dispose();
                        mmFile.Dispose();
                        File.Delete(mmFileName);
                        return new byte[0];
                    }

                    if (accessor.ReadByte(4) != SSH2_AGENT_SIGN_RESPONSE)
                    {
                        accessor.Dispose();
                        mmFile.Dispose();
                        File.Delete(mmFileName);
                        return new byte[0];
                    }

                    int size = IPAddress.HostToNetworkOrder(accessor.ReadInt32(5));
                    var ret = new byte[size];
                    accessor.ReadArray(9, ret, 0, size);

                    accessor.Dispose();
                    mmFile.Dispose();
                    File.Delete(mmFileName);

                    return ret;
                }
            }
        }

        #endregion
    }
}

Viewing all articles
Browse latest Browse all 1729

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>