Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: All the Client API work and dependencies rolled in to one monster PR #1139

Closed
wants to merge 62 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
fa13191
add initial client api code
Feb 22, 2017
90660e7
adding client interface back in
Feb 22, 2017
3fac89b
basic factory for local/remote client
Feb 23, 2017
b024930
clientapi works with cli
Feb 24, 2017
f2f3118
grpc interceptors are working, need to get proper token auth in place
endophage Mar 6, 2017
7760a77
regenerated certs for all the services and server side of tokens shou…
Mar 8, 2017
44656cc
grpc client needed GetGUN method to meet Repository interface
Mar 8, 2017
bc29fa6
fixing some interfaces
Mar 8, 2017
2386ae0
server side of producing a token is working
Mar 9, 2017
cc73b50
working token auth end to end
Mar 14, 2017
02415db
Add Target operations to client API protobuf definitions and generate…
n4ss Mar 7, 2017
a0095e8
Add ChangeList operations to client API protobuf definitions
n4ss Mar 7, 2017
904cf35
Add generated code for ChangeList grpc interface
n4ss Mar 7, 2017
7bba7ec
Add Init, Publish and returned Errors to client API gRPC interface
n4ss Mar 7, 2017
9066aa3
Add Role operations to client API gRPC interface with generated code
n4ss Mar 7, 2017
55ad281
Add remaining rpc definitions to client gRPC API interface
n4ss Mar 7, 2017
0da0e82
Implement client api ListTargets
n4ss Mar 11, 2017
8cd2776
Implement more client api calls
n4ss Mar 12, 2017
4d8d088
Implement more client api calls - part 2
n4ss Mar 12, 2017
6c0fd1e
Implement more client api calls - part 3
n4ss Mar 12, 2017
3c4ca95
Implement more client api calls - part 4
n4ss Mar 12, 2017
c5208b6
Implement more client api calls - part 5
n4ss Mar 13, 2017
822b5e4
Finish implementing main part of client API endpoint
n4ss Mar 13, 2017
1af5845
Switch Empty type to google protobuf's Empty type
n4ss Mar 13, 2017
dd7c918
Add cryptoservice interface to client api endpoint
n4ss Mar 13, 2017
1ad6d9d
Add missing response type and update generated files
n4ss Mar 13, 2017
adca046
Add client api prototypes to server interface
n4ss Mar 13, 2017
c63fb30
Fix cherry-pick conflicts
n4ss Mar 14, 2017
270b9f3
Add GUN parameters to client side of client api
n4ss Mar 14, 2017
158c945
Implement cient api server-side Init and Publish
n4ss Mar 14, 2017
8e3faf6
Implement more cient api server-side - part 2
n4ss Mar 15, 2017
ac1b131
Implement more cient api server-side - part 3
n4ss Mar 15, 2017
bb89cff
Finish cient api server-side implementation
n4ss Mar 15, 2017
c82dade
Fix cherry-pick conflicts
n4ss Mar 16, 2017
e21831c
moving around some of the auth stuff to collect it better in one plac…
Mar 17, 2017
e6e7e88
use relative path for API CA in cmd/notary/config.json so it works fo…
Mar 20, 2017
cdfd8df
removing test that was intentionally failing. I was just using it to …
Mar 20, 2017
bcc3abe
forward tokens from ClientAPI to notary server
Mar 30, 2017
297656c
configure key storage for clientapi
Mar 30, 2017
1841e0c
wildcarded trustpinning for cert ids
Mar 30, 2017
894c960
update gorm to reduce size of #1110
Apr 4, 2017
7bceca2
addressing riyaz's review
Mar 31, 2017
64da591
Add export tuf command
n4ss Mar 27, 2017
fb3f1c3
Fix export command for delegations
n4ss Mar 28, 2017
475cb36
Do not duplicate targets for delegations
n4ss Mar 28, 2017
e0c59b9
Create an Export cache to hook on notary repo caching
n4ss Apr 3, 2017
896913f
Allow cache injection on top of configured notary repo
n4ss Apr 3, 2017
f080c62
Refactor export cmd with a hook on the cache and add import through p…
n4ss Apr 3, 2017
b0b3c4d
Import hook on remote store's SetMulti rather than repo's Publish
n4ss Apr 4, 2017
1949bf1
Directly use HTTPStore as a remote to load the new metadata
n4ss Apr 4, 2017
bc0f3f1
making lint,vet,etc... pass
Apr 11, 2017
8583f60
some cleanup of the export store
Apr 11, 2017
62586ec
making import super simple: "notary import gun role file"
Apr 11, 2017
2cc5c31
working basic version of add to file directly, no tests
Apr 4, 2017
9ab801d
generate any key and output it to a pair of .pub and .priv files
Apr 7, 2017
1d4737b
bugfixes
Apr 13, 2017
a8eac65
some refactoring and more bugfixes for client api
Apr 13, 2017
3972417
final fixes to work with prod
Apr 13, 2017
1c7b2e7
Move default locally/remotely managed role keys to a package local var
n4ss Apr 14, 2017
ace8293
catalog tokens for cryptoservice operations
Apr 13, 2017
362c486
fixing server managed snapshots for Client API
Apr 14, 2017
791ceaf
include seperate configs and compose files for full local dev, and de…
Apr 14, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ ifneq ($(GITUNTRACKEDCHANGES),)
GITCOMMIT := $(GITCOMMIT)-dirty
endif
CTIMEVAR=-X $(NOTARY_PKG)/version.GitCommit=$(GITCOMMIT) -X $(NOTARY_PKG)/version.NotaryVersion=$(NOTARY_VERSION)
GO_LDFLAGS=-ldflags "-w $(CTIMEVAR)"
GO_LDFLAGS=-ldflags "-s -w $(CTIMEVAR)"
GO_LDFLAGS_STATIC=-ldflags "-w $(CTIMEVAR) -extldflags -static"
GOOSES = darwin linux windows
NOTARY_BUILDTAGS ?= pkcs11
Expand Down
222 changes: 222 additions & 0 deletions auth/client/authchallenge.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
package client

import (
"net/http"
"net/url"
"strings"
)

// Challenge carries information from a WWW-Authenticate response header.
// See RFC 2617.
type Challenge struct {
// Scheme is the auth-scheme according to RFC 2617
Scheme string

// Parameters are the auth-params according to RFC 2617
Parameters map[string]string
}

// Manager manages the challenges for endpoints.
// The challenges are pulled out of HTTP responses. Only
// responses which expect challenges should be added to
// the manager, since a non-unauthorized request will be
// viewed as not requiring challenges.
type Manager interface {
// GetChallenges returns the challenges for the given
// endpoint URL.
GetChallenges(endpoint url.URL) ([]Challenge, error)

// AddResponse adds the response to the challenge
// manager. The challenges will be parsed out of
// the WWW-Authenicate headers and added to the
// URL which was produced the response. If the
// response was authorized, any challenges for the
// endpoint will be cleared.
AddResponse(resp *http.Response) error
}

// NewSimpleManager returns an instance of
// Manger which only maps endpoints to challenges
// based on the responses which have been added the
// manager. The simple manager will make no attempt to
// perform requests on the endpoints or cache the responses
// to a backend.
//func NewSimpleManager() Manager {
// return &simpleManager{
// Challanges: make(map[string][]Challenge),
// }
//}
//
//type simpleManager struct {
// sync.RWMutex
// Challanges map[string][]Challenge
//}
//
//func normalizeURL(endpoint *url.URL) {
// endpoint.Host = strings.ToLower(endpoint.Host)
// endpoint.Host = canonicalAddr(endpoint)
//}
//
//func (m *simpleManager) GetChallenges(endpoint url.URL) ([]Challenge, error) {
// normalizeURL(&endpoint)
//
// m.RLock()
// defer m.RUnlock()
// challenges := m.Challanges[endpoint.String()]
// return challenges, nil
//}
//
//func (m *simpleManager) AddResponse(resp *http.Response) error {
// challenges := ResponseChallenges(resp)
// if resp.Request == nil {
// return fmt.Errorf("missing request reference")
// }
// urlCopy := url.URL{
// Path: resp.Request.URL.Path,
// Host: resp.Request.URL.Host,
// Scheme: resp.Request.URL.Scheme,
// }
// normalizeURL(&urlCopy)
//
// m.Lock()
// defer m.Unlock()
// m.Challanges[urlCopy.String()] = challenges
// return nil
//}

// Octet types from RFC 2616.
type octetType byte

var octetTypes [256]octetType

const (
isToken octetType = 1 << iota
isSpace
)

func init() {
// OCTET = <any 8-bit sequence of data>
// CHAR = <any US-ASCII character (octets 0 - 127)>
// CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
// CR = <US-ASCII CR, carriage return (13)>
// LF = <US-ASCII LF, linefeed (10)>
// SP = <US-ASCII SP, space (32)>
// HT = <US-ASCII HT, horizontal-tab (9)>
// <"> = <US-ASCII double-quote mark (34)>
// CRLF = CR LF
// LWS = [CRLF] 1*( SP | HT )
// TEXT = <any OCTET except CTLs, but including LWS>
// separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <">
// | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT
// token = 1*<any CHAR except CTLs or separators>
// qdtext = <any TEXT except <">>

for c := 0; c < 256; c++ {
var t octetType
isCtl := c <= 31 || c == 127
isChar := 0 <= c && c <= 127
isSeparator := strings.IndexRune(" \t\"(),/:;<=>?@[]\\{}", rune(c)) >= 0
if strings.IndexRune(" \t\r\n", rune(c)) >= 0 {
t |= isSpace
}
if isChar && !isCtl && !isSeparator {
t |= isToken
}
octetTypes[c] = t
}
}

func ParseAuthHeader(header []string) []Challenge {
challenges := []Challenge{}
for _, h := range header {
v, p := parseValueAndParams(h)
if v != "" {
challenges = append(challenges, Challenge{Scheme: v, Parameters: p})
}
}
return challenges
}

func parseValueAndParams(header string) (value string, params map[string]string) {
params = make(map[string]string)
value, s := expectToken(header)
if value == "" {
return
}
value = strings.ToLower(value)
s = "," + skipSpace(s)
for strings.HasPrefix(s, ",") {
var pkey string
pkey, s = expectToken(skipSpace(s[1:]))
if pkey == "" {
return
}
if !strings.HasPrefix(s, "=") {
return
}
var pvalue string
pvalue, s = expectTokenOrQuoted(s[1:])
if pvalue == "" {
return
}
pkey = strings.ToLower(pkey)
params[pkey] = pvalue
s = skipSpace(s)
}
return
}

func skipSpace(s string) (rest string) {
i := 0
for ; i < len(s); i++ {
if octetTypes[s[i]]&isSpace == 0 {
break
}
}
return s[i:]
}

func expectToken(s string) (token, rest string) {
i := 0
for ; i < len(s); i++ {
if octetTypes[s[i]]&isToken == 0 {
break
}
}
return s[:i], s[i:]
}

func expectTokenOrQuoted(s string) (value string, rest string) {
if !strings.HasPrefix(s, "\"") {
return expectToken(s)
}
s = s[1:]
for i := 0; i < len(s); i++ {
switch s[i] {
case '"':
return s[:i], s[i+1:]
case '\\':
p := make([]byte, len(s)-1)
j := copy(p, s[:i])
escape := true
for i = i + 1; i < len(s); i++ {
b := s[i]
switch {
case escape:
escape = false
p[j] = b
j++
case b == '\\':
escape = true
case b == '"':
return string(p[:j]), s[i+1:]
default:
p[j] = b
j++
}
}
return "", ""
}
}
return "", ""
}
Loading