gitee.com/Mydawng/fabric-ca@v2.0.0-alpha.0.20201214145411-9ea68369cb61+incompatible/lib/caerrors/servererror.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package caerrors
     8  
     9  import (
    10  	"encoding/json"
    11  	"fmt"
    12  	"net/http"
    13  	"reflect"
    14  
    15  	cfsslapi "github.com/cloudflare/cfssl/api"
    16  	"github.com/cloudflare/cfssl/log"
    17  	"github.com/pkg/errors"
    18  )
    19  
    20  // Error codes
    21  const (
    22  	// Unknown error code
    23  	ErrUnknown = 0
    24  	// HTTP method not allowed
    25  	ErrMethodNotAllowed = 1
    26  	// No authorization header was found in request
    27  	ErrNoAuthHdr = 2
    28  	// Failed reading the HTTP request body
    29  	ErrReadingReqBody = 3
    30  	// HTTP request body was empty but should not have been
    31  	ErrEmptyReqBody = 4
    32  	// HTTP request body was of the wrong format
    33  	ErrBadReqBody = 5
    34  	// The token in the authorization header was invalid
    35  	ErrBadReqToken = 6
    36  	// The caller does not have the "hf.Revoker" attibute
    37  	ErrNotRevoker = 7
    38  	// Certificate to be revoked was not found
    39  	ErrRevCertNotFound = 8
    40  	// Certificate to be revoked is not owned by expected user
    41  	ErrCertWrongOwner = 9
    42  	// Identity of certificate to be revoked was not found
    43  	ErrRevokeIDNotFound = 10
    44  	// User info was not found for issuee of revoked certificate
    45  	ErrRevokeUserInfoNotFound = 11
    46  	// Certificate revocation failed for another reason
    47  	ErrRevokeFailure = 12
    48  	// Failed to update user info when revoking identity
    49  	ErrRevokeUpdateUser = 13
    50  	// Failed to revoke any certificates by identity
    51  	ErrNoCertsRevoked = 14
    52  	// Missing fields in the revocation request
    53  	ErrMissingRevokeArgs = 15
    54  	// Failed to get user's affiliation
    55  	ErrGettingAffiliation = 16
    56  	// Revoker's affiliation not equal to or above revokee's affiliation
    57  	ErrRevokerNotAffiliated = 17
    58  	// Failed to send an HTTP response
    59  	ErrSendingResponse = 18
    60  	// The CA (Certificate Authority) name was not found
    61  	ErrCANotFound = 19
    62  	// Authorization failure
    63  	ErrAuthenticationFailure = 20
    64  	// No username and password were in the authorization header
    65  	ErrNoUserPass = 21
    66  	// Enrollment is currently disabled for the server
    67  	ErrEnrollDisabled = 22
    68  	// Invalid user name
    69  	ErrInvalidUser = 23
    70  	// Invalid password
    71  	ErrInvalidPass = 24
    72  	// Invalid token in authorization header
    73  	ErrInvalidToken = 25
    74  	// Certificate was not issued by a trusted authority
    75  	ErrUntrustedCertificate = 26
    76  	// Certificate has expired
    77  	ErrCertExpired = 27
    78  	// Certificate has been revoked
    79  	ErrCertRevoked = 28
    80  	// Failed trying to check if certificate is revoked
    81  	ErrCertRevokeCheckFailure = 29
    82  	// Certificate was not found
    83  	ErrCertNotFound = 30
    84  	// Bad certificate signing request
    85  	ErrBadCSR = 31
    86  	// Failed to get identity's prekey
    87  	ErrNoPreKey = 32
    88  	// The caller was not authenticated
    89  	ErrCallerIsNotAuthenticated = 33
    90  	// Invalid configuration setting
    91  	ErrConfig = 34
    92  	// The caller does not have authority to generate a CRL
    93  	ErrNoGenCRLAuth = 35
    94  	// Invalid RevokedAfter value in the GenCRL request
    95  	ErrInvalidRevokedAfter = 36
    96  	// Invalid ExpiredAfter value in the GenCRL request
    97  	ErrInvalidExpiredAfter = 37
    98  	// Failed to get revoked certs from the database
    99  	ErrRevokedCertsFromDB = 38
   100  	// Failed to get CA cert
   101  	ErrGetCACert = 39
   102  	// Failed to get CA signer
   103  	ErrGetCASigner = 40
   104  	// Failed to generate CRL
   105  	ErrGenCRL = 41
   106  	// Registrar does not have the authority to register an attribute
   107  	ErrRegAttrAuth = 42
   108  	// Registrar does not own 'hf.Registrar.Attributes'
   109  	ErrMissingRegAttr = 43
   110  	// Caller does not have appropriate affiliation to perform requested action
   111  	ErrCallerNotAffiliated = 44
   112  	// Failed to verify if caller has appropriate type
   113  	ErrGettingType = 45
   114  	// CA cert does not have 'crl sign' usage
   115  	ErrNoCrlSignAuth = 46
   116  	// Incorrect level of database
   117  	ErrDBLevel = 47
   118  	// Incorrect level of configuration file
   119  	ErrConfigFileLevel = 48
   120  	// Failed to get user from database
   121  	ErrGettingUser = 49
   122  	// Error processing HTTP request
   123  	ErrHTTPRequest = 50
   124  	// Error connecting to database
   125  	ErrConnectingDB = 51
   126  	// Failed to add identity
   127  	ErrAddIdentity = 52
   128  	// Unauthorized to perform update action
   129  	ErrUpdateConfigAuth = 53
   130  	// Registrar not authorized to act on type
   131  	ErrRegistrarInvalidType = 54
   132  	// Registrar not authorized to act on affiliation
   133  	ErrRegistrarNotAffiliated = 55
   134  	// Failed to remove identity
   135  	ErrRemoveIdentity = 56
   136  	// Failed to get boolean query parameter
   137  	ErrGettingBoolQueryParm = 57
   138  	// Failed to modify identity
   139  	ErrModifyingIdentity = 58
   140  	// Caller does not have the appropriate role
   141  	ErrMissingRole = 59
   142  	// Failed to add new affiliation
   143  	ErrUpdateConfigAddAff = 60
   144  	// Failed to remove affiliation
   145  	ErrUpdateConfigRemoveAff = 61
   146  	// Error occured while removing affiliation in database
   147  	ErrRemoveAffDB = 62
   148  	// Error occured when making a Get request to database
   149  	ErrDBGet = 63
   150  	// Failed to modiy affiliation
   151  	ErrUpdateConfigModifyAff = 64
   152  	// Error occured while deleting user
   153  	ErrDBDeleteUser = 65
   154  	// Certificate that is being revoked has already been revoked
   155  	ErrCertAlreadyRevoked = 66
   156  	// Failed to get requested certificate(s)
   157  	ErrGettingCert = 67
   158  	// Error occurred parsing variable as an integer
   159  	ErrParsingIntEnvVar = 68
   160  	// CA certificate file is not found warning message
   161  	ErrCACertFileNotFound = 69
   162  	// Error occurs when invoking a request revoked enrollment ID
   163  	ErrRevokedID = 70
   164  	// Authorization failure
   165  	ErrAuthorizationFailure = 71
   166  	// Action is not allowed when using LDAP
   167  	ErrInvalidLDAPAction = 72
   168  	// Incorrect password limit reached
   169  	ErrPasswordAttempts = 73
   170  	// Registering multiple identities with same name
   171  	ErrDupIdentityReg = 74
   172  	// Error occured registering identity
   173  	ErrRegisteringIdentity = 75
   174  	// Registrat does not have authority to register identity
   175  	ErrRegistrarRegAuth = 76
   176  	// Common name does not match username during enroll
   177  	ErrCNInvalidEnroll = 77
   178  	// Invoker does not have required attribute to perform function
   179  	ErrInvokerMissAttr = 78
   180  	// Invalid boolean value for attribute
   181  	ErrInvalidBool = 79
   182  	// Input validation failed on CSR
   183  	ErrInputValidCSR = 80
   184  	// Error occurred while generating attribute extension
   185  	ErrAttrExt = 81
   186  	// Error for invalid max enrolment registeration value
   187  	ErrInvalidMaxEnroll = 82
   188  )
   189  
   190  // CreateHTTPErr constructs a new HTTP error.
   191  func CreateHTTPErr(scode, code int, format string, args ...interface{}) *HTTPErr {
   192  	msg := fmt.Sprintf(format, args...)
   193  	return &HTTPErr{
   194  		scode: scode,
   195  		lcode: code,
   196  		lmsg:  msg,
   197  		rcode: code,
   198  		rmsg:  msg,
   199  	}
   200  }
   201  
   202  // NewHTTPErr constructs a new HTTP error wrappered with pkg/errors error.
   203  func NewHTTPErr(scode, code int, format string, args ...interface{}) error {
   204  	return CreateHTTPErr(scode, code, format, args...)
   205  }
   206  
   207  // NewAuthenticationErr constructs an HTTP error specifically indicating an authentication failure.
   208  // The local code and message is specific, but the remote code and message is generic
   209  // for security reasons.
   210  func NewAuthenticationErr(code int, format string, args ...interface{}) error {
   211  	he := CreateHTTPErr(401, code, format, args...)
   212  	he.Remote(ErrAuthenticationFailure, "Authentication failure")
   213  	return he
   214  }
   215  
   216  // NewAuthorizationErr constructs an HTTP error specifically indicating an authorization failure.
   217  // The local code and message is specific, but the remote code and message is generic
   218  // for security reasons.
   219  func NewAuthorizationErr(code int, format string, args ...interface{}) error {
   220  	he := CreateHTTPErr(403, code, format, args...)
   221  	he.Remote(ErrAuthorizationFailure, "Authorization failure")
   222  	return he
   223  }
   224  
   225  // Print prints a properly formatted http error string
   226  func Print(err error) string {
   227  	he := GetCause(err)
   228  	if he != nil {
   229  		return he.Print()
   230  	}
   231  	return err.Error()
   232  }
   233  
   234  // HTTPErr is an HTTP error.
   235  // "local" refers to errors as logged in the server (local to the server).
   236  // "remote" refers to errors as returned to the client (remote to the server).
   237  // This allows us to log a more specific error in the server logs while
   238  // returning a more generic error to the client, as is done for authorization
   239  // failures.
   240  type HTTPErr struct {
   241  	scode int    // HTTP status code
   242  	lcode int    // local error code
   243  	lmsg  string // local error message
   244  	rcode int    // remote error code
   245  	rmsg  string // remote error message
   246  }
   247  
   248  // Error returns the string representation
   249  func (he *HTTPErr) Error() string {
   250  	return he.String()
   251  }
   252  
   253  // String returns a string representation of this augmented error
   254  func (he *HTTPErr) String() string {
   255  	return he.lmsg
   256  }
   257  
   258  // Remote sets the remote code and message to something different from that of the local code and message
   259  func (he *HTTPErr) Remote(code int, format string, args ...interface{}) *HTTPErr {
   260  	he.rcode = code
   261  	he.rmsg = fmt.Sprintf(format, args...)
   262  	return he
   263  }
   264  
   265  type errorWriter interface {
   266  	http.ResponseWriter
   267  }
   268  
   269  // Write the server's HTTP error response
   270  func (he *HTTPErr) writeResponse(w errorWriter) error {
   271  	response := cfsslapi.NewErrorResponse(he.rmsg, he.rcode)
   272  	jsonMessage, err := json.Marshal(response)
   273  	if err != nil {
   274  		log.Errorf("Failed to marshal error to JSON: %v", err)
   275  		return err
   276  	}
   277  	msg := string(jsonMessage)
   278  	http.Error(w, msg, he.scode)
   279  	return nil
   280  }
   281  
   282  // GetRemoteCode returns the remote error code
   283  func (he *HTTPErr) GetRemoteCode() int {
   284  	return he.rcode
   285  }
   286  
   287  // GetLocalCode returns the local error code
   288  func (he *HTTPErr) GetLocalCode() int {
   289  	return he.lcode
   290  }
   291  
   292  // GetStatusCode returns the HTTP status code
   293  func (he *HTTPErr) GetStatusCode() int {
   294  	return he.scode
   295  }
   296  
   297  // GetRemoteMsg returns the remote error message
   298  func (he *HTTPErr) GetRemoteMsg() string {
   299  	return he.rmsg
   300  }
   301  
   302  // GetLocalMsg returns the local error message
   303  func (he *HTTPErr) GetLocalMsg() string {
   304  	return he.lmsg
   305  }
   306  
   307  // Print will print a properly formated error message
   308  func (he *HTTPErr) Print() string {
   309  	if he.lcode == he.rcode && he.lmsg == he.rmsg {
   310  		return fmt.Sprintf("scode: %d, code: %d, msg: %s", he.scode, he.lcode, he.lmsg)
   311  	}
   312  	return fmt.Sprintf("scode: %d, local code: %d, local msg: %s, remote code: %d, remote msg: %s",
   313  		he.scode, he.lcode, he.lmsg, he.rcode, he.rmsg)
   314  }
   315  
   316  // ServerErr contains error message with corresponding CA error code
   317  type ServerErr struct {
   318  	code int
   319  	msg  string
   320  }
   321  
   322  // FatalErr is a server error that is will prevent the server/CA from continuing to operate
   323  type FatalErr struct {
   324  	ServerErr
   325  }
   326  
   327  // NewServerError constructs a server error
   328  func NewServerError(code int, format string, args ...interface{}) *ServerErr {
   329  	msg := fmt.Sprintf(format, args...)
   330  	return &ServerErr{
   331  		code: code,
   332  		msg:  msg,
   333  	}
   334  }
   335  
   336  // NewFatalError constructs a fatal error
   337  func NewFatalError(code int, format string, args ...interface{}) *FatalErr {
   338  	msg := fmt.Sprintf(format, args...)
   339  	return &FatalErr{
   340  		ServerErr{
   341  			code: code,
   342  			msg:  msg,
   343  		},
   344  	}
   345  }
   346  
   347  func (fe *FatalErr) Error() string {
   348  	return fe.String()
   349  }
   350  
   351  func (fe *FatalErr) String() string {
   352  	return fmt.Sprintf("Code: %d - %s", fe.code, fe.msg)
   353  }
   354  
   355  // IsFatalError return true if the error is of type 'FatalErr'
   356  func IsFatalError(err error) bool {
   357  	causeErr := errors.Cause(err)
   358  	typ := reflect.TypeOf(causeErr)
   359  	// If a pointer to a struct is passe, get the type of the dereferenced object
   360  	if typ.Kind() == reflect.Ptr {
   361  		typ = typ.Elem()
   362  	}
   363  
   364  	if typ == reflect.TypeOf(FatalErr{}) {
   365  		return true
   366  	}
   367  	return false
   368  }
   369  
   370  type causer interface {
   371  	Cause() error
   372  }
   373  
   374  // GetCause gets the root cause of the error
   375  func GetCause(err error) *HTTPErr {
   376  	for err != nil {
   377  		switch err.(type) {
   378  		case *HTTPErr:
   379  			return err.(*HTTPErr)
   380  		case causer:
   381  			err = err.(causer).Cause()
   382  		default:
   383  			return nil
   384  		}
   385  	}
   386  	return nil
   387  }