1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
14 "git.arvados.org/arvados.git/sdk/go/arvados"
15 "git.arvados.org/arvados.git/sdk/go/httpserver"
16 "golang.org/x/crypto/ssh"
19 // AuthorizedKeyCreate checks that the provided public key is valid,
20 // then proxies to railsproxy.
21 func (conn *Conn) AuthorizedKeyCreate(ctx context.Context, opts arvados.CreateOptions) (arvados.AuthorizedKey, error) {
22 if err := validateKey(opts.Attrs); err != nil {
23 return arvados.AuthorizedKey{}, httpserver.ErrorWithStatus(err, http.StatusBadRequest)
25 return conn.railsProxy.AuthorizedKeyCreate(ctx, opts)
28 // AuthorizedKeyUpdate checks that the provided public key is valid,
29 // then proxies to railsproxy.
30 func (conn *Conn) AuthorizedKeyUpdate(ctx context.Context, opts arvados.UpdateOptions) (arvados.AuthorizedKey, error) {
31 if err := validateKey(opts.Attrs); err != nil {
32 return arvados.AuthorizedKey{}, httpserver.ErrorWithStatus(err, http.StatusBadRequest)
34 return conn.railsProxy.AuthorizedKeyUpdate(ctx, opts)
37 func validateKey(attrs map[string]interface{}) error {
38 in, _ := attrs["public_key"].(string)
42 in = strings.TrimSpace(in)
43 if strings.IndexAny(in, "\r\n") >= 0 {
44 return errors.New("Public key does not appear to be valid: extra data after key")
46 pubkey, _, _, rest, err := ssh.ParseAuthorizedKey([]byte(in))
48 return fmt.Errorf("Public key does not appear to be valid: %w", err)
51 return errors.New("Public key does not appear to be valid: extra data after key")
53 if i := strings.Index(in, " "); i < 0 {
54 return errors.New("Public key does not appear to be valid: no leading type field")
55 } else if in[:i] != pubkey.Type() {
56 return fmt.Errorf("Public key does not appear to be valid: leading type field %q does not match actual key type %q", in[:i], pubkey.Type())