client_auth.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. // Copyright 2011 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package ssh
  5. import (
  6. "errors"
  7. "fmt"
  8. "io"
  9. "net"
  10. )
  11. // authenticate authenticates with the remote server. See RFC 4252.
  12. func (c *ClientConn) authenticate(session []byte) error {
  13. // initiate user auth session
  14. if err := c.writePacket(marshal(msgServiceRequest, serviceRequestMsg{serviceUserAuth})); err != nil {
  15. return err
  16. }
  17. packet, err := c.readPacket()
  18. if err != nil {
  19. return err
  20. }
  21. var serviceAccept serviceAcceptMsg
  22. if err := unmarshal(&serviceAccept, packet, msgServiceAccept); err != nil {
  23. return err
  24. }
  25. // during the authentication phase the client first attempts the "none" method
  26. // then any untried methods suggested by the server.
  27. tried, remain := make(map[string]bool), make(map[string]bool)
  28. for auth := ClientAuth(new(noneAuth)); auth != nil; {
  29. ok, methods, err := auth.auth(session, c.config.User, c.transport, c.config.rand())
  30. if err != nil {
  31. return err
  32. }
  33. if ok {
  34. // success
  35. return nil
  36. }
  37. tried[auth.method()] = true
  38. delete(remain, auth.method())
  39. for _, meth := range methods {
  40. if tried[meth] {
  41. // if we've tried meth already, skip it.
  42. continue
  43. }
  44. remain[meth] = true
  45. }
  46. auth = nil
  47. for _, a := range c.config.Auth {
  48. if remain[a.method()] {
  49. auth = a
  50. break
  51. }
  52. }
  53. }
  54. return fmt.Errorf("ssh: unable to authenticate, attempted methods %v, no supported methods remain", keys(tried))
  55. }
  56. func keys(m map[string]bool) (s []string) {
  57. for k := range m {
  58. s = append(s, k)
  59. }
  60. return
  61. }
  62. // HostKeyChecker represents a database of known server host keys.
  63. type HostKeyChecker interface {
  64. // Check is called during the handshake to check server's
  65. // public key for unexpected changes. The hostKey argument is
  66. // in SSH wire format. It can be parsed using
  67. // ssh.ParsePublicKey. The address before DNS resolution is
  68. // passed in the addr argument, so the key can also be checked
  69. // against the hostname.
  70. Check(addr string, remote net.Addr, algorithm string, hostKey []byte) error
  71. }
  72. // A ClientAuth represents an instance of an RFC 4252 authentication method.
  73. type ClientAuth interface {
  74. // auth authenticates user over transport t.
  75. // Returns true if authentication is successful.
  76. // If authentication is not successful, a []string of alternative
  77. // method names is returned.
  78. auth(session []byte, user string, t *transport, rand io.Reader) (bool, []string, error)
  79. // method returns the RFC 4252 method name.
  80. method() string
  81. }
  82. // "none" authentication, RFC 4252 section 5.2.
  83. type noneAuth int
  84. func (n *noneAuth) auth(session []byte, user string, t *transport, rand io.Reader) (bool, []string, error) {
  85. if err := t.writePacket(marshal(msgUserAuthRequest, userAuthRequestMsg{
  86. User: user,
  87. Service: serviceSSH,
  88. Method: "none",
  89. })); err != nil {
  90. return false, nil, err
  91. }
  92. return handleAuthResponse(t)
  93. }
  94. func (n *noneAuth) method() string {
  95. return "none"
  96. }
  97. // "password" authentication, RFC 4252 Section 8.
  98. type passwordAuth struct {
  99. ClientPassword
  100. }
  101. func (p *passwordAuth) auth(session []byte, user string, t *transport, rand io.Reader) (bool, []string, error) {
  102. type passwordAuthMsg struct {
  103. User string
  104. Service string
  105. Method string
  106. Reply bool
  107. Password string
  108. }
  109. pw, err := p.Password(user)
  110. if err != nil {
  111. return false, nil, err
  112. }
  113. if err := t.writePacket(marshal(msgUserAuthRequest, passwordAuthMsg{
  114. User: user,
  115. Service: serviceSSH,
  116. Method: "password",
  117. Reply: false,
  118. Password: pw,
  119. })); err != nil {
  120. return false, nil, err
  121. }
  122. return handleAuthResponse(t)
  123. }
  124. func (p *passwordAuth) method() string {
  125. return "password"
  126. }
  127. // A ClientPassword implements access to a client's passwords.
  128. type ClientPassword interface {
  129. // Password returns the password to use for user.
  130. Password(user string) (password string, err error)
  131. }
  132. // ClientAuthPassword returns a ClientAuth using password authentication.
  133. func ClientAuthPassword(impl ClientPassword) ClientAuth {
  134. return &passwordAuth{impl}
  135. }
  136. // ClientKeyring implements access to a client key ring.
  137. type ClientKeyring interface {
  138. // Key returns the i'th Publickey, or nil if no key exists at i.
  139. Key(i int) (key PublicKey, err error)
  140. // Sign returns a signature of the given data using the i'th key
  141. // and the supplied random source.
  142. Sign(i int, rand io.Reader, data []byte) (sig []byte, err error)
  143. }
  144. // "publickey" authentication, RFC 4252 Section 7.
  145. type publickeyAuth struct {
  146. ClientKeyring
  147. }
  148. type publickeyAuthMsg struct {
  149. User string
  150. Service string
  151. Method string
  152. // HasSig indicates to the reciver packet that the auth request is signed and
  153. // should be used for authentication of the request.
  154. HasSig bool
  155. Algoname string
  156. Pubkey string
  157. // Sig is defined as []byte so marshal will exclude it during validateKey
  158. Sig []byte `ssh:"rest"`
  159. }
  160. func (p *publickeyAuth) auth(session []byte, user string, t *transport, rand io.Reader) (bool, []string, error) {
  161. // Authentication is performed in two stages. The first stage sends an
  162. // enquiry to test if each key is acceptable to the remote. The second
  163. // stage attempts to authenticate with the valid keys obtained in the
  164. // first stage.
  165. var index int
  166. // a map of public keys to their index in the keyring
  167. validKeys := make(map[int]PublicKey)
  168. for {
  169. key, err := p.Key(index)
  170. if err != nil {
  171. return false, nil, err
  172. }
  173. if key == nil {
  174. // no more keys in the keyring
  175. break
  176. }
  177. if ok, err := p.validateKey(key, user, t); ok {
  178. validKeys[index] = key
  179. } else {
  180. if err != nil {
  181. return false, nil, err
  182. }
  183. }
  184. index++
  185. }
  186. // methods that may continue if this auth is not successful.
  187. var methods []string
  188. for i, key := range validKeys {
  189. pubkey := MarshalPublicKey(key)
  190. algoname := key.PublicKeyAlgo()
  191. sign, err := p.Sign(i, rand, buildDataSignedForAuth(session, userAuthRequestMsg{
  192. User: user,
  193. Service: serviceSSH,
  194. Method: p.method(),
  195. }, []byte(algoname), pubkey))
  196. if err != nil {
  197. return false, nil, err
  198. }
  199. // manually wrap the serialized signature in a string
  200. s := serializeSignature(key.PublicKeyAlgo(), sign)
  201. sig := make([]byte, stringLength(len(s)))
  202. marshalString(sig, s)
  203. msg := publickeyAuthMsg{
  204. User: user,
  205. Service: serviceSSH,
  206. Method: p.method(),
  207. HasSig: true,
  208. Algoname: algoname,
  209. Pubkey: string(pubkey),
  210. Sig: sig,
  211. }
  212. p := marshal(msgUserAuthRequest, msg)
  213. if err := t.writePacket(p); err != nil {
  214. return false, nil, err
  215. }
  216. success, methods, err := handleAuthResponse(t)
  217. if err != nil {
  218. return false, nil, err
  219. }
  220. if success {
  221. return success, methods, err
  222. }
  223. }
  224. return false, methods, nil
  225. }
  226. // validateKey validates the key provided it is acceptable to the server.
  227. func (p *publickeyAuth) validateKey(key PublicKey, user string, t *transport) (bool, error) {
  228. pubkey := MarshalPublicKey(key)
  229. algoname := key.PublicKeyAlgo()
  230. msg := publickeyAuthMsg{
  231. User: user,
  232. Service: serviceSSH,
  233. Method: p.method(),
  234. HasSig: false,
  235. Algoname: algoname,
  236. Pubkey: string(pubkey),
  237. }
  238. if err := t.writePacket(marshal(msgUserAuthRequest, msg)); err != nil {
  239. return false, err
  240. }
  241. return p.confirmKeyAck(key, t)
  242. }
  243. func (p *publickeyAuth) confirmKeyAck(key PublicKey, t *transport) (bool, error) {
  244. pubkey := MarshalPublicKey(key)
  245. algoname := key.PublicKeyAlgo()
  246. for {
  247. packet, err := t.readPacket()
  248. if err != nil {
  249. return false, err
  250. }
  251. switch packet[0] {
  252. case msgUserAuthBanner:
  253. // TODO(gpaul): add callback to present the banner to the user
  254. case msgUserAuthPubKeyOk:
  255. msg := userAuthPubKeyOkMsg{}
  256. if err := unmarshal(&msg, packet, msgUserAuthPubKeyOk); err != nil {
  257. return false, err
  258. }
  259. if msg.Algo != algoname || msg.PubKey != string(pubkey) {
  260. return false, nil
  261. }
  262. return true, nil
  263. case msgUserAuthFailure:
  264. return false, nil
  265. default:
  266. return false, UnexpectedMessageError{msgUserAuthSuccess, packet[0]}
  267. }
  268. }
  269. panic("unreachable")
  270. }
  271. func (p *publickeyAuth) method() string {
  272. return "publickey"
  273. }
  274. // ClientAuthKeyring returns a ClientAuth using public key authentication.
  275. func ClientAuthKeyring(impl ClientKeyring) ClientAuth {
  276. return &publickeyAuth{impl}
  277. }
  278. // handleAuthResponse returns whether the preceding authentication request succeeded
  279. // along with a list of remaining authentication methods to try next and
  280. // an error if an unexpected response was received.
  281. func handleAuthResponse(t *transport) (bool, []string, error) {
  282. for {
  283. packet, err := t.readPacket()
  284. if err != nil {
  285. return false, nil, err
  286. }
  287. switch packet[0] {
  288. case msgUserAuthBanner:
  289. // TODO: add callback to present the banner to the user
  290. case msgUserAuthFailure:
  291. msg := userAuthFailureMsg{}
  292. if err := unmarshal(&msg, packet, msgUserAuthFailure); err != nil {
  293. return false, nil, err
  294. }
  295. return false, msg.Methods, nil
  296. case msgUserAuthSuccess:
  297. return true, nil, nil
  298. case msgDisconnect:
  299. return false, nil, io.EOF
  300. default:
  301. return false, nil, UnexpectedMessageError{msgUserAuthSuccess, packet[0]}
  302. }
  303. }
  304. panic("unreachable")
  305. }
  306. // ClientAuthAgent returns a ClientAuth using public key authentication via
  307. // an agent.
  308. func ClientAuthAgent(agent *AgentClient) ClientAuth {
  309. return ClientAuthKeyring(&agentKeyring{agent: agent})
  310. }
  311. // agentKeyring implements ClientKeyring.
  312. type agentKeyring struct {
  313. agent *AgentClient
  314. keys []*AgentKey
  315. }
  316. func (kr *agentKeyring) Key(i int) (key PublicKey, err error) {
  317. if kr.keys == nil {
  318. if kr.keys, err = kr.agent.RequestIdentities(); err != nil {
  319. return
  320. }
  321. }
  322. if i >= len(kr.keys) {
  323. return
  324. }
  325. return kr.keys[i].Key()
  326. }
  327. func (kr *agentKeyring) Sign(i int, rand io.Reader, data []byte) (sig []byte, err error) {
  328. var key PublicKey
  329. if key, err = kr.Key(i); err != nil {
  330. return
  331. }
  332. if key == nil {
  333. return nil, errors.New("ssh: key index out of range")
  334. }
  335. if sig, err = kr.agent.SignRequest(key, data); err != nil {
  336. return
  337. }
  338. // Unmarshal the signature.
  339. var ok bool
  340. if _, sig, ok = parseString(sig); !ok {
  341. return nil, errors.New("ssh: malformed signature response from agent")
  342. }
  343. if sig, _, ok = parseString(sig); !ok {
  344. return nil, errors.New("ssh: malformed signature response from agent")
  345. }
  346. return sig, nil
  347. }
  348. // ClientKeyboardInteractive should prompt the user for the given
  349. // questions.
  350. type ClientKeyboardInteractive interface {
  351. // Challenge should print the questions, optionally disabling
  352. // echoing (eg. for passwords), and return all the answers.
  353. // Challenge may be called multiple times in a single
  354. // session. After successful authentication, the server may
  355. // send a challenge with no questions, for which the user and
  356. // instruction messages should be printed. RFC 4256 section
  357. // 3.3 details how the UI should behave for both CLI and
  358. // GUI environments.
  359. Challenge(user, instruction string, questions []string, echos []bool) ([]string, error)
  360. }
  361. // ClientAuthKeyboardInteractive returns a ClientAuth using a
  362. // prompt/response sequence controlled by the server.
  363. func ClientAuthKeyboardInteractive(impl ClientKeyboardInteractive) ClientAuth {
  364. return &keyboardInteractiveAuth{impl}
  365. }
  366. type keyboardInteractiveAuth struct {
  367. ClientKeyboardInteractive
  368. }
  369. func (c *keyboardInteractiveAuth) method() string {
  370. return "keyboard-interactive"
  371. }
  372. func (c *keyboardInteractiveAuth) auth(session []byte, user string, t *transport, rand io.Reader) (bool, []string, error) {
  373. type initiateMsg struct {
  374. User string
  375. Service string
  376. Method string
  377. Language string
  378. Submethods string
  379. }
  380. if err := t.writePacket(marshal(msgUserAuthRequest, initiateMsg{
  381. User: user,
  382. Service: serviceSSH,
  383. Method: "keyboard-interactive",
  384. })); err != nil {
  385. return false, nil, err
  386. }
  387. for {
  388. packet, err := t.readPacket()
  389. if err != nil {
  390. return false, nil, err
  391. }
  392. // like handleAuthResponse, but with less options.
  393. switch packet[0] {
  394. case msgUserAuthBanner:
  395. // TODO: Print banners during userauth.
  396. continue
  397. case msgUserAuthInfoRequest:
  398. // OK
  399. case msgUserAuthFailure:
  400. var msg userAuthFailureMsg
  401. if err := unmarshal(&msg, packet, msgUserAuthFailure); err != nil {
  402. return false, nil, err
  403. }
  404. return false, msg.Methods, nil
  405. case msgUserAuthSuccess:
  406. return true, nil, nil
  407. default:
  408. return false, nil, UnexpectedMessageError{msgUserAuthInfoRequest, packet[0]}
  409. }
  410. var msg userAuthInfoRequestMsg
  411. if err := unmarshal(&msg, packet, packet[0]); err != nil {
  412. return false, nil, err
  413. }
  414. // Manually unpack the prompt/echo pairs.
  415. rest := msg.Prompts
  416. var prompts []string
  417. var echos []bool
  418. for i := 0; i < int(msg.NumPrompts); i++ {
  419. prompt, r, ok := parseString(rest)
  420. if !ok || len(r) == 0 {
  421. return false, nil, errors.New("ssh: prompt format error")
  422. }
  423. prompts = append(prompts, string(prompt))
  424. echos = append(echos, r[0] != 0)
  425. rest = r[1:]
  426. }
  427. if len(rest) != 0 {
  428. return false, nil, fmt.Errorf("ssh: junk following message %q", rest)
  429. }
  430. answers, err := c.Challenge(msg.User, msg.Instruction, prompts, echos)
  431. if err != nil {
  432. return false, nil, err
  433. }
  434. if len(answers) != len(prompts) {
  435. return false, nil, errors.New("ssh: not enough answers from keyboard-interactive callback")
  436. }
  437. responseLength := 1 + 4
  438. for _, a := range answers {
  439. responseLength += stringLength(len(a))
  440. }
  441. serialized := make([]byte, responseLength)
  442. p := serialized
  443. p[0] = msgUserAuthInfoResponse
  444. p = p[1:]
  445. p = marshalUint32(p, uint32(len(answers)))
  446. for _, a := range answers {
  447. p = marshalString(p, []byte(a))
  448. }
  449. if err := t.writePacket(serialized); err != nil {
  450. return false, nil, err
  451. }
  452. }
  453. }