Skip to content

Commit

Permalink
Feat: Implement Hauth verification
Browse files Browse the repository at this point in the history
- added /hauth endpoint for capturing hauth
- added hauth verification
- update readme file with info about hauth and basic auth
- update some workflows
- added config section under security for hauth
  • Loading branch information
ajmandourah committed Oct 14, 2024
1 parent 97a07f0 commit c818669
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 2 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ jobs:
packages: write

steps:
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Checkout repository
uses: actions/checkout@v3
with:
Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ security:
# - Device-Id: Switch fingerprint
# Response with status code other than 200 will be treated as failure
forwardAuth: https://auth.tinshop.com/switch
# Hauth code you obtain from tinfoil. This is unique to your domain and help protect against forged requests
hauth: XXXXXXXXXXXXX

# This section describe all custom title db to show up properly in tinfoil
customTitledb:
Expand Down Expand Up @@ -234,6 +236,22 @@ All of the settings in the `config.yaml` file are valid Environment Variables. T
| TINSHOP_SECURITY_BLACKLIST | sources.blacklist | `null` | `NSWID4 NSWID5 NSWID6` |
| TINSHOP_SECURITY_FORWARDAUTH | sources.forwardAuth | `null` | `https://auth.tinshop.com/switch` |

## Using HAUTH for your site

Hauth is signature of the request Url scheme and hostname is sent via "HAUTH: XXXXXXXXXXXXXX" header. This value is unique to your domain, and helps prevent forged requests.
To use it with Tinshop-ng do the following:
- Run tinshop-ng as usual and add it to tinfoil
- When adding to tinfoil , add a path `/hauth` to your server information in the path section.
- close and reopen tinfoil then Navigate to file browser and click on your server name you added.
- observer your tinshop-ng logs. you should be getting a log message with the hauth code in it. make sure the host matches your sites domain.
- edit your config.yaml with `hauth: YOUR_HAURH_CODE` under the security section. Make sure its under the security section and indented as in the example.
- All done. any requests from any client other than tinfoil will need to have this secret code inside otherwise it won't accept connections. you can test it out by inputting a false code.
- To cancel hauth verification comment its part in the config.yaml file.

## Some notes about basic auth

Basic auth is umm 'basic' and it has its limitation. some characthers like @ and $ cannot be used as it will mess up the url. stick to alphanumerical long passwords for the time being.

## 🥍 Want to do cross-build generation?

Wanting to generate all possible os binaries (macOS, linux, windows) with all architectures (arm, amd64)?
Expand Down
5 changes: 5 additions & 0 deletions config.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ security:
# Response with status code other than 200 will be treated as failure
forwardAuth: https://auth.tinshop.com/switch

#Hauth verification:
#This value is unique to your domain, and helps prevent forged requests.
#fill this value with the value got from tinfoil. read the wiki for more information.
# hauth: XXXXXXXXXXXXXX

# This section describe all custom title db to show up properly in tinfoil
customTitledb:
# Id of the entry
Expand Down
9 changes: 9 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type security struct {
Blacklist []string `mapstructure:"blacklist"`
BannedTheme []string `mapstructure:"bannedTheme"`
ForwardAuth string `mapstructure:"forwardAuth"`
Hauth string `mapstructure:"hauth"`
}

type nsp struct {
Expand Down Expand Up @@ -94,6 +95,8 @@ func (cfg *Configuration) LoadConfig() {
viper.SetDefault("security.whitelist", []string{})
viper.SetDefault("security.blacklist", []string{})
viper.SetDefault("security.forwardAuth", "")
viper.SetDefault("security.hauth", "")


viper.SetEnvPrefix("TINSHOP")
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
Expand Down Expand Up @@ -333,6 +336,12 @@ func (cfg *Configuration) ForwardAuthURL() string {
return cfg.Security.ForwardAuth
}

//get Hauth code
func (cfg *Configuration) Get_Hauth() string {
return cfg.Security.Hauth
}


// IsBlacklisted tells if the uid is blacklisted or not
func (cfg *Configuration) IsBlacklisted(uid string) bool {
if len(cfg.Security.Whitelist) != 0 {
Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func createShop() TinShop {
r.HandleFunc("/api/{endpoint}", shop.APIHandler)
r.NotFoundHandler = http.HandlerFunc(notFound)
r.MethodNotAllowedHandler = http.HandlerFunc(notAllowed)
r.Use(shop.StatsMiddleware)
// r.Use(shop.StatsMiddleware)
r.Use(shop.TinfoilMiddleware)
r.Use(shop.CORSMiddleware)
http.Handle("/", r)
Expand Down
1 change: 1 addition & 0 deletions repository/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type Config interface {
SetShopTemplateData(ShopTemplate)

ForwardAuthURL() string
Get_Hauth() string
IsBlacklisted(string) bool
IsWhitelisted(string) bool
IsBannedTheme(string) bool
Expand Down
20 changes: 19 additions & 1 deletion security.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ func (s *TinShop) TinfoilMiddleware(next http.Handler) http.Handler {
return
}

log.Println(s.Shop.Config.Get_Hauth())

//Show Hauth for the specefied host
//tinfoil sends requests appending "/" at the end
if r.RequestURI == "/hauth/" && r.Header.Get("Hauth") != "" {
log.Println("HAUTH for ", s.Shop.Config.Host(), " is: ", headers["Hauth"])
return
}

if r.RequestURI == "/" || utils.IsValidFilter(cleanPath(r.RequestURI)) {
// Check for blacklist/whitelist
var uid = strings.Join(headers["Uid"], "")
Expand Down Expand Up @@ -71,9 +80,17 @@ func (s *TinShop) TinfoilMiddleware(next http.Handler) http.Handler {
return
}


//Hauth check
if s.Shop.Config.Get_Hauth() != "" && r.Header.Get("Hauth") != s.Shop.Config.Get_Hauth(){
log.Println("Hauth header mismatch. Possible attempt to access shop from a possible forged request. ", r.RemoteAddr)
return
}


// Enforce true tinfoil queries
// TODO: Check Uauth and Hauth headers
log.Printf("Switch %s, %s, %s, %s, %s, %s requesting %s", headers["Theme"], headers["Uid"], headers["Version"], headers["Language"], headers["Hauth"], headers["Uauth"], r.RequestURI)
log.Printf("Switch %s requesting %s", headers["Uid"], r.RequestURI)

// Check user password
if s.Shop.Config.ForwardAuthURL() != "" && headers["Authorization"] != nil {
Expand All @@ -90,6 +107,7 @@ func (s *TinShop) TinfoilMiddleware(next http.Handler) http.Handler {
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
log.Println("Wrong credentials enterd from switch ",r.Header.Get("Uid"), " " ,r.RemoteAddr)
_ = shopTemplate.Execute(w, s.Shop.Config.ShopTemplateData())
return
}
Expand Down

0 comments on commit c818669

Please sign in to comment.