Skip to content

Commit

Permalink
WIP: added basis for config restore
Browse files Browse the repository at this point in the history
  • Loading branch information
scusi committed Jul 9, 2018
1 parent 5a03ee2 commit acc1814
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 30 deletions.
23 changes: 23 additions & 0 deletions cmd/client/main.go
Expand Up @@ -50,6 +50,7 @@ var saltHex string // submit salt to register process
var showUsername bool
var toraddr string
var outFile string // file to write output, overrides original filename
var restore string // userid to restore

func init() {
flag.StringVar(&toraddr, "socksproxy", "", "set a socks proxy (e.g. tor) to be used to connect to the server")
Expand Down Expand Up @@ -78,6 +79,7 @@ func init() {
flag.BoolVar(&registerNewMachine, "register-new-host", false, "registers a new machine with a given userID")
flag.BoolVar(&unregisterMachine, "unregister-host", false, "invalidates the machine access, deletes local config")
flag.StringVar(&outFile, "o", "", "write to this filename")
flag.StringVar(&restore, "restore", "", "userID to restore locally")
}

func checkFatal(err error) {
Expand Down Expand Up @@ -109,6 +111,23 @@ func main() {
// delete APIToken for that machine OR force a new APIToken onto the account.
// delete APIToken for that machine OR force a new APIToken onto the account.
}
if restore != "" {
// load config from server
// ask user for minilock credentials
email, password := askpass.Credentials()
keys, err := minilock.GenerateKey(email, password)
checkFatal(err)
//pubID, err := keys.EncodeID()
//checkFatal(err)
c, err := client.New(
client.SetUsername(restore),
client.SetURL(URL),
client.SetKeys(keys))
err = c.GetConfigOnServer()
checkFatal(err)
log.Printf("Client: %+v\n", c)
return
}

// register
if register {
Expand Down Expand Up @@ -170,6 +189,9 @@ func main() {
c.Socksproxy = toraddr
cy, err := yaml.Marshal(c)
checkFatal(err)
// save the config on the server
err = c.SaveConfigOnServer()
checkFatal(err)
// make sure that the path exists
clientConfigFile = filepath.Join(
usr.HomeDir, ".config",
Expand Down Expand Up @@ -213,6 +235,7 @@ func main() {
checkFatal(err)
err = yaml.Unmarshal(data, &c)
checkFatal(err)

if showUsername {
fmt.Printf("Your secureShareUsername is: '%s'\n", c.Username)
return
Expand Down
45 changes: 16 additions & 29 deletions cmd/server/ConfigHandler.go
@@ -1,31 +1,34 @@
package main

import (
"bufio"
"bytes"
"github.com/gorilla/mux"
"io"
"io/ioutil"
"log"
"net/http"
"path/filepath"
"strings"
//"strings"
)

func ConfigHandler(w http.ResponseWriter, r *http.Request) {
log.Printf("entering ConfigHandler...\n")
/* We can not authenticate because we have no ApiKey on the client yet.
username := r.Header.Get("Apiusername")
token := r.Header.Get("Apikey")
if userDB.APIAuthenticate(username, token) != true {
http.Error(w, "Unauthorized", 401)
return
}
*/
vars := mux.Vars(r)
userID := vars["UserID"]

switch r.Method {
case "GET":
log.Printf("ConfigHandler GET\n")
// send config to client aka download
filePath := strings.Join([]string{userID, "config"}, "/")
data, err := fileStore.Read(filePath)
//filePath := strings.Join([]string{userID, "config"}, "/")
filePath := filepath.Join(userID, "config")
data, err := clientStore.Read(filePath)
if err != nil {
log.Printf("ERROR downloading '%s': %s\n", filePath, err.Error())
http.Error(w, "file not found", 404)
Expand All @@ -41,34 +44,18 @@ func ConfigHandler(w http.ResponseWriter, r *http.Request) {
log.Printf("written %d byte to client\n", n)
return
case "POST":
log.Printf("ConfigHandler POST\n")
// retrieve config from client and store aka upload
var inBuf bytes.Buffer
inWrt := bufio.NewWriter(&inBuf)
reader, err := r.MultipartReader()
bodyBytes, err := ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
http.Error(w, err.Error(), 500)
return
}
for {
part, err := reader.NextPart()
if err == io.EOF {
break
}
if part.FileName() == "" {
continue
}
if _, err = io.Copy(inWrt, part); err != nil {
log.Printf("Error copy file part: %s\n", err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
filePath := filepath.Join(userID, "config")
err = clientStore.Write(filePath, inBuf.Bytes())
if err != nil {
log.Println(err)
}
filePath := filepath.Join(userID, "config")
err = clientStore.Write(filePath, bodyBytes)
if err != nil {
log.Println(err)
}
return
}
return
}
2 changes: 1 addition & 1 deletion cmd/server/main.go
Expand Up @@ -118,8 +118,8 @@ func main() {
})
// initialize http router
router := mux.NewRouter().StrictSlash(true)
router.HandleFunc("/{UserID}/{FileID}", Download)
router.HandleFunc("/config/{UserID}", ConfigHandler).Name("ConfigHandler")
router.HandleFunc("/{UserID}/{FileID}", Download)
router.HandleFunc("/upload/", Upload)
router.HandleFunc("/list/", List)
router.HandleFunc("/register/", Register)
Expand Down
102 changes: 102 additions & 0 deletions libs/client/client.go
Expand Up @@ -7,6 +7,7 @@ import (
"crypto/rand"
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
"github.com/cathalgarvey/go-minilock"
"github.com/cathalgarvey/go-minilock/taber"
Expand Down Expand Up @@ -195,6 +196,107 @@ func (c *Client) UpdateKey(username string) (pubKey string, err error) {
return
}

func (c *Client) SaveConfigOnServer() (err error) {
// marshal client
clientBytes, err := json.Marshal(c)
if err != nil {
return
}
// encrypt clientBytes
// TODO: minilock.EncryptFileContents()
// create save request
bodyReader := bytes.NewReader(clientBytes)
urlString := c.URL + "config/" + c.Username
req, err := http.NewRequest("POST", urlString, bodyReader)
if err != nil {
return
}
if Debug {
dump, _ := httputil.DumpRequestOut(req, false)
log.Printf("%s", dump)
}
// send request
resp, err := c.Do(req)
if err != nil {
return
}
if Debug {
dump, _ := httputil.DumpResponse(resp, true)
log.Printf("%s", dump)
}
// check response
if resp.StatusCode != 200 {
log.Printf("status code (%d) is NOT OK\n", resp.StatusCode)
body, readErr := ioutil.ReadAll(resp.Body)
if readErr != nil {
return readErr
}
log.Printf("Server error: '%s'\n", body)
err = fmt.Errorf("Server error: '%s'\n", body)
return
}
// return
return
}

func (c *Client) GetConfigOnServer() (err error) {
urlString := c.URL + "config/" + c.Username
req, err := http.NewRequest("GET", urlString, nil)
if err != nil {
return
}
if Debug {
dump, _ := httputil.DumpRequestOut(req, false)
log.Printf("%s", dump)
}
// send request
resp, err := c.Do(req)
if err != nil {
return
}
if Debug {
dump, _ := httputil.DumpResponse(resp, true)
log.Printf("%s", dump)
}
// check response
if resp.StatusCode != 200 {
log.Printf("status code (%d) is NOT OK\n", resp.StatusCode)
body, readErr := ioutil.ReadAll(resp.Body)
if readErr != nil {
return readErr
}
log.Printf("Server error: '%s'\n", body)
err = fmt.Errorf("Server error: '%s'\n", body)
return
}
// read body
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return
}
/* // decrypt body
senderID, _, rr, err := minilock.DecryptFileContents(body, c.Keys)
if err != nil {
return
}
if senderID != c.Username {
err = fmt.Errorf("config senderID not correct: '%s' vs. '%s'\n", senderID, c.Username)
return
}
// unmarshal
err = json.Unmarshal(rr, c)
if err != nil {
return
}
*/
// unmarshal
err = json.Unmarshal(body, c)
if err != nil {
return
}
return
}

// Register - register a new user at the secureShareServer
func (c *Client) Register(pubID string) (user, token, mID, mToken string, err error) {
v := url.Values{}
Expand Down

0 comments on commit acc1814

Please sign in to comment.