Skip to content

Commit

Permalink
Merge pull request #127 from readium/feature/shiny-frontend
Browse files Browse the repository at this point in the history
Feature/shiny frontend
  • Loading branch information
danielweck authored Mar 1, 2017
2 parents e6e7fe1 + 496a811 commit 3bc3cdd
Show file tree
Hide file tree
Showing 140 changed files with 7,562 additions and 513 deletions.
11 changes: 10 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,22 @@ lcpencrypt/lcpencrypt
files/
*.sqlite*
config.yaml
lcpserver/manage/config.js
.vscode/launch.json
debug
*.exe
*.yaml

**/manage/config.js
frontend/manage/node_modules/*
frontend/manage/dist/*
frontend/manage/js/*
frontend/manage/js/components/*
*.map
*.htpasswd
lcpserver/test.sqllite
.DS_Store
.vscode
lcpencrypt/.DS_Store
lcpserver/.DS_Store
npm-debug.log
manage/config.js
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@ NOTE: here is a license section snippet:
```json
license:
links:
hint: "http://www.edrlab.org/static/hint.html"
publication: "http://www.edrlab.org/files/{publication_id}"
status: "http://www.edrlab.org/licenses/{license_id}/status"
hint: "http://www.edrlab.org/readiumlcp/static/hint.html"
publication: "http://www.edrlab.org/readiumlcp/files/{publication_id}"
status: "http://www.edrlab.org/readiumlcp/licenses/{license_id}/status"
```

"license_status": parameters related to the interactions implemented by the License Status server, if any
Expand All @@ -174,8 +174,16 @@ NOTE: list files for localization (ex: 'en-US.json, de-DE.json') must match the
- log_directory: point to log file (a .log).
- compliance_tests_mode_on: boolean; if `true`, logging is turned on.


The following CBC / GCM configurable property is DISABLED, see https://github.com/readium/readium-lcp-server/issues/109
"aes256_cbc_or_gcm": either "GCM" or "CBC" (which is the default value). This is used only for encrypting publication resources, not the content key, not the user key check, not the LCP license fields.


Documentation
============
Detailed documentation can be found in the [Wiki pages](../../wiki) of the project.


Contributing
============
Please make a Pull Request with tests at github.com/readium/readium-lcp-server
18 changes: 11 additions & 7 deletions api/common_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
"github.com/urfave/negroni"
"github.com/jeffbmartinez/delay"
"github.com/technoweenie/grohl"
"github.com/rs/cors"

"github.com/readium/readium-lcp-server/problem"
)
Expand Down Expand Up @@ -95,12 +96,13 @@ func CreateServerRouter(tplPath string) ServerRouter {
// Does not insert CORS headers as intended, depends on Origin check in the HTTP request...we want the same headers, always.
// IMPORT "github.com/rs/cors"
// //https://github.com/rs/cors#parameters
// c := cors.New(cors.Options{
// AllowedOrigins: []string{"*"},
// AllowedMethods: []string{"POST", "GET", "OPTIONS", "PUT", "DELETE"},
// Debug: true,
// })
// n.Use(c)
c := cors.New(cors.Options{
AllowedOrigins: []string{"*"},
AllowedMethods: []string{"PATCH", "HEAD", "POST", "GET", "OPTIONS", "PUT", "DELETE"},
AllowedHeaders: []string{"Range", "Content-Type", "Origin", "X-Requested-With", "Accept", "Accept-Language", "Content-Language", "Authorization"},
Debug: true,
})
n.Use(c)

n.UseHandler(r)

Expand Down Expand Up @@ -139,8 +141,10 @@ func ExtraLogger(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc)
func CORSHeaders(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {

grohl.Log(grohl.Data{"CORS": "yes"})
rw.Header().Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
rw.Header().Add("Access-Control-Allow-Methods", "PATCH, HEAD, POST, GET, OPTIONS, PUT, DELETE")
rw.Header().Add("Access-Control-Allow-Credentials", "true")
rw.Header().Add("Access-Control-Allow-Origin", "*")
rw.Header().Add("Access-Control-Allow-Headers", "Range, Content-Type, Origin, X-Requested-With, Accept, Accept-Language, Content-Language, Authorization")

// before
next(rw, r)
Expand Down
64 changes: 45 additions & 19 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package config

Expand All @@ -35,18 +35,20 @@ import (
)

type Configuration struct {
Certificate Certificate `yaml:"certificate"`
Storage Storage `yaml:"storage"`
License License `yaml:"license"`
LcpServer ServerInfo `yaml:"lcp"`
LsdServer ServerInfo `yaml:"lsd"`
LsdNotifyAuth Auth `yaml:"lsd_notify_auth"`
LcpUpdateAuth Auth `yaml:"lcp_update_auth"`
Static Static `yaml:"static"`
LicenseStatus LicenseStatus `yaml:"license_status"`
Localization Localization `yaml:"localization"`
Logging Logging `yaml:"logging"`
AES256_CBC_OR_GCM string `yaml:"aes256_cbc_or_gcm,omitempty"`
Certificate Certificate `yaml:"certificate"`
Storage Storage `yaml:"storage"`
License License `yaml:"license"`
LcpServer ServerInfo `yaml:"lcp"`
LsdServer LsdServerInfo `yaml:"lsd"`
FrontendServer FrontendServerInfo `yaml:"frontend"`
LsdNotifyAuth Auth `yaml:"lsd_notify_auth"`
LcpUpdateAuth Auth `yaml:"lcp_update_auth"`
LicenseStatus LicenseStatus `yaml:"license_status"`
Localization Localization `yaml:"localization"`
Logging Logging `yaml:"logging"`

// DISABLED, see https://github.com/readium/readium-lcp-server/issues/109
//AES256_CBC_OR_GCM string `yaml:"aes256_cbc_or_gcm,omitempty"`
}

type ServerInfo struct {
Expand All @@ -56,6 +58,19 @@ type ServerInfo struct {
ReadOnly bool `yaml:"readonly,omitempty"`
PublicBaseUrl string `yaml:"public_base_url,omitempty"`
Database string `yaml:"database,omitempty"`
Directory string `yaml:"directory,omitempty"`
}

type LsdServerInfo struct {
ServerInfo `yaml:",inline"`
LicenseLinkUrl string `yaml:"license_link_url,omitempty"`
}

type FrontendServerInfo struct {
ServerInfo `yaml:",inline"`
ProviderID string `yaml:"provider_id"`
MasterRepository string `yaml:"master_repository"`
EncryptedRepository string `yaml:"encrypted_repository"`
}

type Auth struct {
Expand All @@ -72,10 +87,6 @@ type FileSystem struct {
Directory string `yaml:"directory"`
}

type Static struct {
Directory string `yaml:"directory"`
}

type Storage struct {
FileSystem FileSystem `yaml:"filesystem"`
AccessId string `yaml:"access_id"`
Expand Down Expand Up @@ -123,14 +134,15 @@ func ReadConfig(configFileName string) {
}

err = yaml.Unmarshal(yamlFile, &Config)

if err != nil {
panic("Can't unmarshal config. " + configFileName + " -> " + err.Error())
}
}

func SetPublicUrls() error {
var lcpPublicBaseUrl, lsdPublicBaseUrl, lcpHost, lsdHost string
var lcpPort, lsdPort int
var lcpPublicBaseUrl, lsdPublicBaseUrl, frontendPublicBaseUrl, lcpHost, lsdHost, frontendHost string
var lcpPort, lsdPort, frontendPort int
var err error

if lcpHost = Config.LcpServer.Host; lcpHost == "" {
Expand All @@ -147,12 +159,22 @@ func SetPublicUrls() error {
}
}

if frontendHost = Config.FrontendServer.Host; frontendHost == "" {
frontendHost, err = os.Hostname()
if err != nil {
return err
}
}

if lcpPort = Config.LcpServer.Port; lcpPort == 0 {
lcpPort = 8989
}
if lsdPort = Config.LsdServer.Port; lsdPort == 0 {
lsdPort = 8990
}
if frontendPort = Config.FrontendServer.Port; frontendPort == 0 {
frontendPort = 80
}

if lcpPublicBaseUrl = Config.LcpServer.PublicBaseUrl; lcpPublicBaseUrl == "" {
lcpPublicBaseUrl = "http://" + lcpHost + ":" + strconv.Itoa(lcpPort)
Expand All @@ -162,6 +184,10 @@ func SetPublicUrls() error {
lsdPublicBaseUrl = "http://" + lsdHost + ":" + strconv.Itoa(lsdPort)
Config.LsdServer.PublicBaseUrl = lsdPublicBaseUrl
}
if frontendPublicBaseUrl = Config.FrontendServer.PublicBaseUrl; frontendPublicBaseUrl == "" {
frontendPublicBaseUrl = "http://" + frontendHost + ":" + strconv.Itoa(frontendPort)
Config.FrontendServer.PublicBaseUrl = frontendPublicBaseUrl
}

return err
}
10 changes: 6 additions & 4 deletions crypto/aes_cbc.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package crypto

Expand All @@ -40,6 +40,7 @@ const (
)

func (e cbcEncrypter) Signature() string {
// W3C padding scheme, not PKCS#7 (see last parameter "insertPadLengthAll" [false] of PaddedReader constructor)
return "http://www.w3.org/2001/04/xmlenc#aes256-cbc"
}

Expand All @@ -49,7 +50,8 @@ func (e cbcEncrypter) GenerateKey() (ContentKey, error) {
}

func (e cbcEncrypter) Encrypt(key ContentKey, r io.Reader, w io.Writer) error {
r = PaddedReader(r, aes.BlockSize)

r = PaddedReader(r, aes.BlockSize, false)

block, err := aes.NewCipher(key)
if err != nil {
Expand Down Expand Up @@ -99,12 +101,12 @@ func (c cbcEncrypter) Decrypt(key ContentKey, r io.Reader, w io.Writer) error {
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(buf[aes.BlockSize:], buf[aes.BlockSize:])

padding := buf[len(buf)-1]
padding := buf[len(buf)-1] // padding length valid for both PKCS#7 and W3C schemes
w.Write(buf[aes.BlockSize : len(buf)-int(padding)])

return nil
}

func NewAESCBCEncrypter() Encrypter {
return cbcEncrypter(struct{}{})
}
}
18 changes: 11 additions & 7 deletions crypto/encrypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ package crypto
import (
"crypto/aes"
"io"

"github.com/readium/readium-lcp-server/config"
)
//"github.com/readium/readium-lcp-server/config"
// FOR: config.Config.AES256_CBC_OR_GCM

type Encrypter interface {
Encrypt(key ContentKey, r io.Reader, w io.Writer) error
Expand All @@ -43,11 +43,15 @@ type Decrypter interface {
}

func NewAESEncrypter_PUBLICATION_RESOURCES() Encrypter {
if config.Config.AES256_CBC_OR_GCM == "GCM" {
return NewAESGCMEncrypter()
} else { // default to CBC
return NewAESCBCEncrypter()
}

return NewAESCBCEncrypter()

// DISABLED, see https://github.com/readium/readium-lcp-server/issues/109
// if config.Config.AES256_CBC_OR_GCM == "GCM" {
// return NewAESGCMEncrypter()
// } else { // default to CBC
// return NewAESCBCEncrypter()
// }
}

func NewAESEncrypter_CONTENT_KEY() Encrypter {
Expand Down
25 changes: 22 additions & 3 deletions crypto/pad.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ package crypto

import (
"io"
"math/rand"
"time"
)

type paddedReader struct {
Expand All @@ -35,6 +37,7 @@ type paddedReader struct {
count byte
left byte
done bool
insertPadLengthAll bool
}

func (r *paddedReader) Read(buf []byte) (int, error) {
Expand Down Expand Up @@ -73,8 +76,21 @@ func (r *paddedReader) Read(buf []byte) (int, error) {

func (r *paddedReader) pad(buf []byte) (i int, err error) {
capacity := cap(buf)

src := rand.New(rand.NewSource(time.Now().UnixNano()))

for i = 0; capacity > 0 && r.left > 0; i++ {
buf[i] = r.count

if (r.insertPadLengthAll) {
buf[i] = r.count
} else {
if r.left == 1 { //capacity == 1 &&
buf[i] = r.count
} else {
buf[i] = byte(src.Intn(254) + 1)
}
}

capacity--
r.left--
}
Expand All @@ -86,6 +102,9 @@ func (r *paddedReader) pad(buf []byte) (i int, err error) {
return
}

func PaddedReader(r io.Reader, blockSize byte) io.Reader {
return &paddedReader{Reader: r, size: blockSize, count: 0, left: 0, done: false}

// insertPadLengthAll = true means PKCS#7 (padding length inserted in each padding slot),
// otherwise false means padding length inserted only in the last slot (the rest is random bytes)
func PaddedReader(r io.Reader, blockSize byte, insertPadLengthAll bool) io.Reader {
return &paddedReader{Reader: r, size: blockSize, count: 0, left: 0, done: false, insertPadLengthAll: insertPadLengthAll}
}
Loading

0 comments on commit 3bc3cdd

Please sign in to comment.