| 
									
										
										
										
											2016-01-26 09:29:20 +08:00
										 |  |  | /* | 
					
						
							|  |  |  |  * Minio Cloud Storage, (C) 2016 Minio, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  * you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  * You may obtain a copy of the License at | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *     http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  * See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  * limitations under the License. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  | package cmd | 
					
						
							| 
									
										
										
										
											2016-01-22 08:28:15 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2016-08-11 12:09:31 +08:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2016-01-29 12:48:41 +08:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2016-01-22 08:28:15 +08:00
										 |  |  | 	"time" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-26 09:29:20 +08:00
										 |  |  | 	jwtgo "github.com/dgrijalva/jwt-go" | 
					
						
							| 
									
										
										
										
											2016-01-22 08:28:15 +08:00
										 |  |  | 	"golang.org/x/crypto/bcrypt" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-13 08:08:15 +08:00
										 |  |  | const jwtAlgorithm = "Bearer" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-25 14:26:53 +08:00
										 |  |  | // JWT - jwt auth backend
 | 
					
						
							|  |  |  | type JWT struct { | 
					
						
							| 
									
										
											  
											
												config/main: Re-write config files - add to new config v3
- New config format.
```
{
	"version": "3",
	"address": ":9000",
    "backend": {
          "type": "fs",
          "disk": "/path"
    },
	"credential": {
		"accessKey": "WLGDGYAQYIGI833EV05A",
		"secretKey": "BYvgJM101sHngl2uzjXS/OBF/aMxAN06JrJ3qJlF"
	},
	"region": "us-east-1",
	"logger": {
		"file": {
			"enable": false,
			"fileName": "",
			"level": "error"
		},
		"syslog": {
			"enable": false,
			"address": "",
			"level": "debug"
		},
		"console": {
			"enable": true,
			"level": "fatal"
		}
	}
}
```
New command lines in lieu of supporting XL.
Minio initialize filesystem backend.
~~~
$ minio init fs <path>
~~~
Minio initialize XL backend.
~~~
$ minio init xl <url1>...<url16>
~~~
For 'fs' backend it starts the server.
~~~
$ minio server
~~~
For 'xl' backend it waits for servers to join.
~~~
$ minio server
... [PROGRESS BAR] of servers connecting
~~~
Now on other servers execute 'join' and they connect.
~~~
....
minio join <url1> -- from <url2> && minio server
minio join <url1> -- from <url3> && minio server
...
...
minio join <url1> -- from <url16> && minio server
~~~
											
										 
											2016-02-13 07:27:10 +08:00
										 |  |  | 	credential | 
					
						
							| 
									
										
										
										
											2016-01-22 08:28:15 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-11 12:09:31 +08:00
										 |  |  | // Default each token expires in 100yrs.
 | 
					
						
							| 
									
										
										
										
											2016-01-22 08:28:15 +08:00
										 |  |  | const ( | 
					
						
							| 
									
										
										
										
											2016-08-11 12:09:31 +08:00
										 |  |  | 	defaultTokenExpiry time.Duration = time.Hour * 876000 // 100yrs.
 | 
					
						
							| 
									
										
										
										
											2016-01-22 08:28:15 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-12 12:57:40 +08:00
										 |  |  | // newJWT - returns new JWT object.
 | 
					
						
							| 
									
										
										
										
											2016-08-11 12:09:31 +08:00
										 |  |  | func newJWT(expiry time.Duration) (*JWT, error) { | 
					
						
							| 
									
										
										
										
											2016-07-12 12:57:40 +08:00
										 |  |  | 	if serverConfig == nil { | 
					
						
							| 
									
										
										
										
											2016-08-11 12:09:31 +08:00
										 |  |  | 		return nil, errors.New("Server not initialzed") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if expiry == 0 { | 
					
						
							|  |  |  | 		expiry = defaultTokenExpiry | 
					
						
							| 
									
										
										
										
											2016-07-12 12:57:40 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-01-25 14:26:53 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Save access, secret keys.
 | 
					
						
							| 
									
										
										
										
											2016-07-12 12:57:40 +08:00
										 |  |  | 	cred := serverConfig.GetCredential() | 
					
						
							|  |  |  | 	if !isValidAccessKey.MatchString(cred.AccessKeyID) { | 
					
						
							| 
									
										
										
										
											2016-08-11 12:09:31 +08:00
										 |  |  | 		return nil, errors.New("Invalid access key") | 
					
						
							| 
									
										
										
										
											2016-07-12 12:57:40 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if !isValidSecretKey.MatchString(cred.SecretAccessKey) { | 
					
						
							| 
									
										
										
										
											2016-08-11 12:09:31 +08:00
										 |  |  | 		return nil, errors.New("Invalid secret key") | 
					
						
							| 
									
										
										
										
											2016-07-12 12:57:40 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
											  
											
												config/main: Re-write config files - add to new config v3
- New config format.
```
{
	"version": "3",
	"address": ":9000",
    "backend": {
          "type": "fs",
          "disk": "/path"
    },
	"credential": {
		"accessKey": "WLGDGYAQYIGI833EV05A",
		"secretKey": "BYvgJM101sHngl2uzjXS/OBF/aMxAN06JrJ3qJlF"
	},
	"region": "us-east-1",
	"logger": {
		"file": {
			"enable": false,
			"fileName": "",
			"level": "error"
		},
		"syslog": {
			"enable": false,
			"address": "",
			"level": "debug"
		},
		"console": {
			"enable": true,
			"level": "fatal"
		}
	}
}
```
New command lines in lieu of supporting XL.
Minio initialize filesystem backend.
~~~
$ minio init fs <path>
~~~
Minio initialize XL backend.
~~~
$ minio init xl <url1>...<url16>
~~~
For 'fs' backend it starts the server.
~~~
$ minio server
~~~
For 'xl' backend it waits for servers to join.
~~~
$ minio server
... [PROGRESS BAR] of servers connecting
~~~
Now on other servers execute 'join' and they connect.
~~~
....
minio join <url1> -- from <url2> && minio server
minio join <url1> -- from <url3> && minio server
...
...
minio join <url1> -- from <url16> && minio server
~~~
											
										 
											2016-02-13 07:27:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-12 12:57:40 +08:00
										 |  |  | 	return &JWT{cred}, nil | 
					
						
							| 
									
										
										
										
											2016-01-22 08:28:15 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-12 12:57:40 +08:00
										 |  |  | // GenerateToken - generates a new Json Web Token based on the incoming access key.
 | 
					
						
							|  |  |  | func (jwt *JWT) GenerateToken(accessKey string) (string, error) { | 
					
						
							|  |  |  | 	// Trim spaces.
 | 
					
						
							|  |  |  | 	accessKey = strings.TrimSpace(accessKey) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if !isValidAccessKey.MatchString(accessKey) { | 
					
						
							| 
									
										
										
										
											2016-08-11 12:09:31 +08:00
										 |  |  | 		return "", errors.New("Invalid access key") | 
					
						
							| 
									
										
										
										
											2016-07-12 12:57:40 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-15 05:59:20 +08:00
										 |  |  | 	tUTCNow := time.Now().UTC() | 
					
						
							|  |  |  | 	token := jwtgo.NewWithClaims(jwtgo.SigningMethodHS512, jwtgo.MapClaims{ | 
					
						
							|  |  |  | 		// Token expires in 10hrs.
 | 
					
						
							| 
									
										
										
										
											2016-08-11 12:09:31 +08:00
										 |  |  | 		"exp": tUTCNow.Add(defaultTokenExpiry).Unix(), | 
					
						
							| 
									
										
										
										
											2016-07-15 05:59:20 +08:00
										 |  |  | 		"iat": tUTCNow.Unix(), | 
					
						
							|  |  |  | 		"sub": accessKey, | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2016-04-30 05:24:10 +08:00
										 |  |  | 	return token.SignedString([]byte(jwt.SecretAccessKey)) | 
					
						
							| 
									
										
										
										
											2016-01-22 08:28:15 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-12 12:57:40 +08:00
										 |  |  | // Authenticate - authenticates incoming access key and secret key.
 | 
					
						
							|  |  |  | func (jwt *JWT) Authenticate(accessKey, secretKey string) error { | 
					
						
							|  |  |  | 	// Trim spaces.
 | 
					
						
							|  |  |  | 	accessKey = strings.TrimSpace(accessKey) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if !isValidAccessKey.MatchString(accessKey) { | 
					
						
							| 
									
										
										
										
											2016-08-11 12:09:31 +08:00
										 |  |  | 		return errors.New("Invalid access key") | 
					
						
							| 
									
										
										
										
											2016-01-22 08:28:15 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-07-12 12:57:40 +08:00
										 |  |  | 	if !isValidSecretKey.MatchString(secretKey) { | 
					
						
							| 
									
										
										
										
											2016-08-11 12:09:31 +08:00
										 |  |  | 		return errors.New("Invalid secret key") | 
					
						
							| 
									
										
										
										
											2016-07-12 12:57:40 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if accessKey != jwt.AccessKeyID { | 
					
						
							| 
									
										
										
										
											2016-08-11 12:09:31 +08:00
										 |  |  | 		return errors.New("Access key does not match") | 
					
						
							| 
									
										
										
										
											2016-07-12 12:57:40 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	hashedSecretKey, _ := bcrypt.GenerateFromPassword([]byte(jwt.SecretAccessKey), bcrypt.DefaultCost) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if bcrypt.CompareHashAndPassword(hashedSecretKey, []byte(secretKey)) != nil { | 
					
						
							| 
									
										
										
										
											2016-08-11 12:09:31 +08:00
										 |  |  | 		return errors.New("Authentication failed") | 
					
						
							| 
									
										
										
										
											2016-07-12 12:57:40 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Success.
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2016-01-22 08:28:15 +08:00
										 |  |  | } |