Beispiel #1
0
// NewAuthMiddleware new Auth Middleware
func NewAuthMiddleware(headerKeyLabel string, headerSecretLabel string, config AuthConfig) *RESTGate {
	t := &RESTGate{headerKeyLabel: headerKeyLabel, headerSecretLabel: headerSecretLabel, config: config}

	if headerKeyLabel == "" { //headerKeyLabel must be defined
		if t.config.Debug == true {
			log.Printf("RestGate: headerKeyLabel is not defined.")
		}
		return nil
	}

	//Default Error Messages
	if t.config.ErrorMessages == nil {
		t.config.ErrorMessages = map[int]map[string]string{
			1: e.New(1, "No Key Or Secret", "").Render(),
			2: e.New(2, "Unauthorized Access", "").Render(),
		}
	} else {
		if _, ok := t.config.ErrorMessages[1]; !ok {
			t.config.ErrorMessages[1] = e.New(1, "No Key Or Secret", "").Render()
		}

		if _, ok := t.config.ErrorMessages[2]; !ok {
			t.config.ErrorMessages[2] = e.New(2, "Unauthorized Access", "").Render()
		}
	}

	return t
}
Beispiel #2
0
func NewRoute() *mux.Router {
	routes := mux.NewRouter().StrictSlash(false)
	r := render.New(render.Options{
		Directory:     "templates",
		IndentJSON:    true,
		IsDevelopment: true,
		Layout:        "layout",
	})

	routes.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		r.Text(w, http.StatusOK, "Index page")
	})

	routes.HandleFunc("/template", func(w http.ResponseWriter, req *http.Request) {
		r.HTML(w, http.StatusOK, "index", nil)
	})

	routes.HandleFunc("/error", func(w http.ResponseWriter, req *http.Request) {

		err := e.New(12, "Unauthorized Access", "Please log in first to access this site")
		r.JSON(w, http.StatusUnauthorized, err.Render())
	})

	routes.HandleFunc("/data", func(w http.ResponseWriter, req *http.Request) {
		r.Data(w, http.StatusOK, []byte("Some binary data here."))
	})

	routes.Handle("/metrics", prometheus.Handler())

	addStaticRoutes(routes)

	return routes
}
Beispiel #3
0
// Returns an Optimus struct which can be used to encode and decode
// integers. Usually used for obfuscating internal ids such as database
// table rows. This method calculates the modInverse computationally.
// Panics if prime is not valid.
func NewCalculated(prime uint64, random uint64) Optimus {
	p := big.NewInt(int64(prime))
	if p.ProbablyPrime(MILLER_RABIN) {
		return Optimus{prime, ModInverse(prime), random}
	} else {
		accuracy := 1.0 - 1.0/math.Pow(float64(4), float64(MILLER_RABIN))
		panic(jsonerror.New(2, "Number is not prime", fmt.Sprintf("%d Miller-Rabin tests done. Accuracy: %f", MILLER_RABIN, accuracy)))
	}
}
Beispiel #4
0
// Calculates the Modular Inverse of a given Prime number such that
// (PRIME * MODULAR_INVERSE) & (MAX_INT_VALUE) = 1
// Panics if n is not a valid prime number.
// See: http://en.wikipedia.org/wiki/Modular_multiplicative_inverse
func ModInverse(n uint64) uint64 {

	p := big.NewInt(int64(n))
	if !p.ProbablyPrime(MILLER_RABIN) {
		accuracy := 1.0 - 1.0/math.Pow(float64(4), float64(MILLER_RABIN))
		panic(jsonerror.New(2, "Number is not prime", fmt.Sprintf("n=%d. %d Miller-Rabin tests done. Accuracy: %f", n, MILLER_RABIN, accuracy)))
	}

	var i big.Int

	prime := big.NewInt(int64(n))
	max := big.NewInt(int64(MAX_INT + 1))

	return i.ModInverse(prime, max).Uint64()
}
Beispiel #5
0
func New(headerKeyLabel string, headerSecretLabel string, store KeyStore, config Config) *RESTGate {
	t := &RESTGate{headerKeyLabel: headerKeyLabel, headerSecretLabel: headerSecretLabel, config: config, store: store}
	log.Printf("RestGate initializing")

	if headerKeyLabel == "" { //headerKeyLabel must be defined
		if t.config.Debug == true {
			log.Printf("RestGate: headerKeyLabel is not defined.")
		}
		return nil
	}

	//Default Error Messages
	if t.config.ErrorMessages == nil {
		t.config.ErrorMessages = map[int]map[string]string{
			1:  e.New(1, "No Key Or Secret", "", "com.github.pjebs.restgate").Render(),
			2:  e.New(2, "Unauthorized Access", "", "com.github.pjebs.restgate").Render(),
			3:  e.New(3, "Please use HTTPS connection", "", "com.github.pjebs.restgate").Render(),
			99: e.New(99, "Software Developers have not setup authentication correctly", "", "com.github.pjebs.restgate").Render(),
		}
	} else {
		if _, ok := t.config.ErrorMessages[1]; !ok {
			t.config.ErrorMessages[1] = e.New(1, "No Key Or Secret", "", "com.github.pjebs.restgate").Render()
		}

		if _, ok := t.config.ErrorMessages[2]; !ok {
			t.config.ErrorMessages[2] = e.New(2, "Unauthorized Access", "", "com.github.pjebs.restgate").Render()
		}

		if _, ok := t.config.ErrorMessages[3]; !ok {
			t.config.ErrorMessages[3] = e.New(3, "Please use HTTPS connection", "", "com.github.pjebs.restgate").Render()
		}

		if _, ok := t.config.ErrorMessages[99]; !ok {
			t.config.ErrorMessages[99] = e.New(99, "Software Developers have not setup authentication correctly", "", "com.github.pjebs.restgate").Render()
		}
	}

	//Check if HTTPS Protection has been turned off
	if t.config.HTTPSProtectionOff {
		//HTTPS Protection is off
		log.Printf("\x1b[31mWARNING: HTTPS Protection is off. This is potentially insecure!\x1b[39;49m")
	}

	return t
}
Beispiel #6
0
func (self *RESTGate) ServeHTTP(w http.ResponseWriter, req *http.Request, next http.HandlerFunc) {

	//Check if HTTPS Protection has been turned off
	if !self.config.HTTPSProtectionOff {
		//HTTPS Protection is on so we must check it
		if !(strings.EqualFold(req.URL.Scheme, "https") || req.TLS != nil) {
			r := render.New(render.Options{})
			r.JSON(w, http.StatusUnauthorized, self.config.ErrorMessages[3]) //"Please use HTTPS connection"
			return
		}
	}

	//Check key in Header
	key := req.Header.Get(self.headerKeyLabel)
	secret := req.Header.Get(self.headerSecretLabel)

	if key == "" {
		//Authentication Information not included in request
		r := render.New(render.Options{})
		r.JSON(w, http.StatusUnauthorized, self.config.ErrorMessages[1]) //"No Key Or Secret"
		return
	}

	authenticationPassed, err := self.store.MatchKey(key, secret)
	if err != nil {
		if self.config.Debug == true {
			log.Printf("RestGate: Run time error: %+v", err)
		}
		r := render.New(render.Options{})
		jerr := e.New(2, err.Error(), "", "com.github.pjebs.restgate").Render()
		r.JSON(w, http.StatusUnauthorized, jerr) //"Unauthorized Access"
	}
	if !authenticationPassed {
		r := render.New(render.Options{})
		r.JSON(w, http.StatusUnauthorized, self.config.ErrorMessages[2]) //"Unauthorized Access"
	} else {
		if self.config.Context != nil {
			self.config.Context(req, key)
		}
		next(w, req)
	}
}
Beispiel #7
0
	"strconv"
	"strings"
	"text/template"
	"time"
)

var minPort int
var holeHost string
var host string
var configPath string
var tplFile = "config.tpl"
var port int
var sg *sendgrid.SGClient

var ErrorMessages = map[int]map[string]string{
	0:  e.New(0, "", "Success").Render(),
	1:  e.New(1, "User is already exists.", "Please try a new one.").Render(),
	2:  e.New(2, "Email is already exists.", "Please try a new one or reset the password.").Render(),
	3:  e.New(3, "Email format error", "Please type a valid email.").Render(),
	4:  e.New(4, "User name or password invalid.", "").Render(),
	5:  e.New(5, "User is confimd or ConfirmationCode is expired.", "Resend a new confirmation code?").Render(),
	6:  e.New(6, "User is confimd.", "No need resend twice.").Render(),
	7:  e.New(7, "User NotFound.", "").Render(),
	8:  e.New(8, "Old password is not correct.", "").Render(),
	9:  e.New(9, "PasswordToken is expired.", "").Render(),
	10: e.New(10, "HoleApp is not exists.", "").Render(),
}

var reEmail, _ = regexp.Compile("(\\w[-._\\w]*\\w@\\w[-._\\w]*\\w\\.\\w{2,3})")

type NewUserForm struct {
Beispiel #8
0
// Generates a valid Optimus struct using a randomly selected prime
// number from this site: http://primes.utm.edu/lists/small/millions/
// The first 50 million prime numbers are distributed evenly in 50 files.
// Parameter req should be nil if not using Google App Engine.
// This Function is Time, Memory and CPU intensive. Run it once to generate the
// required seeds.
// WARNING: Potentially Insecure. Double check that the prime number returned
// is actually prime number using an independent source.
// The largest Prime has 9 digits. The smallest has 1 digit.
// The final return value is the website zip file identifier that was used to obtain the prime number
func GenerateSeed(req *http.Request) (*Optimus, error, uint8) {
	log.Printf("\x1b[31mWARNING: Optimus generates a random number via this site: http://primes.utm.edu/lists/small/millions/. This is potentially insecure!\x1b[39;49m")

	baseURL := "http://primes.utm.edu/lists/small/millions/primes%d.zip"

	//Generate Random number between 1-50
	b_49 := *big.NewInt(49)
	n, _ := rand.Int(rand.Reader, &b_49)
	i_n := n.Uint64() + 1

	//Download zip file
	finalUrl := fmt.Sprintf(baseURL, i_n)
	log.Printf("Using file: %s", finalUrl)

	resp, err := client(req).Get(finalUrl)
	if err != nil {
		return nil, jsonerror.New(1, "Could not generate seed", err.Error()), uint8(i_n)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, jsonerror.New(1, "Could not generate seed", err.Error()), uint8(i_n)
	}

	r, err := zip.NewReader(bytes.NewReader(body), resp.ContentLength)
	if err != nil {
		return nil, jsonerror.New(1, "Could not generate seed", err.Error()), uint8(i_n)
	}

	zippedFile := r.File[0]

	src, err := zippedFile.Open() //src contains ReaderCloser
	if err != nil {
		return nil, jsonerror.New(1, "Could not generate seed", err.Error()), uint8(i_n)
	}
	defer src.Close()

	//Create a Byte Slice
	buf := new(bytes.Buffer)
	noOfBytes, _ := buf.ReadFrom(src)
	b := buf.Bytes() //Byte Slice

	//Randomly pick a character position
	start := 67 // Each zip file has an introductory header which is not relevant until the 67th character
	end := noOfBytes

	b_end := *big.NewInt(int64(end) - int64(start))
	n, _ = rand.Int(rand.Reader, &b_end)
	randomPosition := n.Uint64() + uint64(start)

	min := randomPosition - 9
	max := randomPosition + 9

	if min < uint64(start) {
		min = uint64(start)
	}

	if max > uint64(end) {
		max = uint64(end)
	}

	scanner := bufio.NewScanner(strings.NewReader(string(b[min:max]))) //Input
	scanner.Split(bufio.ScanWords)

	var selectedNumbers []uint64
	for scanner.Scan() {
		p, _ := strconv.ParseUint(scanner.Text(), 10, 64)
		selectedNumbers = append(selectedNumbers, p)
	}

	//Not perfect but good enough

	var selectedPrime uint64
	length := len(selectedNumbers)
	if length > 2 {
		//Pick middle number

		//Check if length is even number
		//Check if round is odd or even
		var odd bool
		if length&1 != 0 {
			odd = true //odd
		} else {
			odd = false //even
		}

		if odd {
			selectedPrime = selectedNumbers[length/2]
		} else {

			r := *big.NewInt(1)
			rn, _ := rand.Int(rand.Reader, &r)
			if rn.Uint64() == 0 {
				selectedPrime = selectedNumbers[length/2]
			} else {
				selectedPrime = selectedNumbers[length/2-1]
			}
		}
	} else {
		//Pick largest number
		largest := selectedNumbers[0]

		for _, value := range selectedNumbers {
			if value > largest {
				largest = value
			}
		}

		selectedPrime = largest
	}

	//Calculate Mod Inverse for selectedPrime
	modInverse := ModInverse(selectedPrime)

	//Generate Random Integer less than MAX_INT
	upper := *big.NewInt(MAX_INT - 2)
	rand, _ := rand.Int(rand.Reader, &upper)
	randomNumber := rand.Uint64() + 1

	return &Optimus{selectedPrime, modInverse, randomNumber}, nil, uint8(i_n)
}
Beispiel #9
0
func New(headerKeyLabel string, headerSecretLabel string, as AuthenticationSource, config Config) *RESTGate {
	t := &RESTGate{headerKeyLabel: headerKeyLabel, headerSecretLabel: headerSecretLabel, source: as, config: config}
	log.Printf("RestGate initializing")

	numberKeys := len(t.config.Key)
	numberSecrets := len(t.config.Secret)

	if numberKeys == 0 { //Key is not set
		if t.config.Debug == true {
			log.Printf("RestGate: Key is not set")
		}
		return nil
	}

	if numberSecrets > numberKeys { //Too many Secret's defined
		if t.config.Debug == true {
			log.Printf("RestGate: Too many Secrets defined. At most there should be 1 secret per key")
		}
		return nil
	}

	if headerKeyLabel == "" { //headerKeyLabel must be defined
		if t.config.Debug == true {
			log.Printf("RestGate: headerKeyLabel is not defined.")
		}
		return nil
	}

	//Default Error Messages
	if t.config.ErrorMessages == nil {
		t.config.ErrorMessages = map[int]map[string]string{
			1:  e.New(1, "No Key Or Secret", "", "com.github.pjebs.restgate").Render(),
			2:  e.New(2, "Unauthorized Access", "", "com.github.pjebs.restgate").Render(),
			99: e.New(99, "Software Developers have not setup authentication correctly", "", "com.github.pjebs.restgate").Render(),
		}
	}

	if as == Database {

		if numberKeys != 1 { //We need exactly 1 Key (it represents field name in database)
			if t.config.Debug == true {
				log.Printf("RestGate: For Database mode, we need exactly 1 Key which represents the field name in the database table")
			}
			return nil
		}

		//Check if database is set.
		//The developer should ensure a database has been selected (i.e. to prevent "No Database selected" error)
		if t.config.DB == nil { //DB is not set
			if t.config.Debug == true {
				log.Printf("RestGate: Database is not set. Be sure that a database name is selected")
			}
			return nil
		}

		//Check if table is set
		if t.config.TableName == "" { //Table name is not set
			if t.config.Debug == true {
				log.Printf("RestGate: For Database mode, a table name is required")
			}
			return nil
		}

	}

	return t
}