You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

80 lines
2.0 KiB

  1. //
  2. // Copyright (c) 2014 David Mzareulyan
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy of this software
  5. // and associated documentation files (the "Software"), to deal in the Software without restriction,
  6. // including without limitation the rights to use, copy, modify, merge, publish, distribute,
  7. // sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
  8. // is furnished to do so, subject to the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be included in all copies or substantial
  11. // portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
  14. // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  15. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  16. // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  17. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  18. //
  19. // +build windows
  20. package sshagent
  21. import (
  22. "errors"
  23. "io"
  24. "net"
  25. "sync"
  26. "golang.org/x/crypto/ssh/agent"
  27. )
  28. // New returns a new agent.Agent and the (custom) connection it uses
  29. // to communicate with a running pagent.exe instance (see README.md)
  30. func New() (agent.Agent, net.Conn, error) {
  31. if !Available() {
  32. return nil, nil, errors.New("SSH agent requested but Pageant not running")
  33. }
  34. return agent.NewClient(&conn{}), nil, nil
  35. }
  36. type conn struct {
  37. sync.Mutex
  38. buf []byte
  39. }
  40. func (c *conn) Close() {
  41. c.Lock()
  42. defer c.Unlock()
  43. c.buf = nil
  44. }
  45. func (c *conn) Write(p []byte) (int, error) {
  46. c.Lock()
  47. defer c.Unlock()
  48. resp, err := query(p)
  49. if err != nil {
  50. return 0, err
  51. }
  52. c.buf = append(c.buf, resp...)
  53. return len(p), nil
  54. }
  55. func (c *conn) Read(p []byte) (int, error) {
  56. c.Lock()
  57. defer c.Unlock()
  58. if len(c.buf) == 0 {
  59. return 0, io.EOF
  60. }
  61. n := copy(p, c.buf)
  62. c.buf = c.buf[n:]
  63. return n, nil
  64. }