From d56ff4786f62578b8cecc725e7735cfb6fd08784 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Thu, 22 Oct 2015 17:50:49 +0200 Subject: [PATCH 01/31] fix switch if no commandline field in POST --- conn.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/conn.go b/conn.go index e6981a75c..45354f743 100644 --- a/conn.go +++ b/conn.go @@ -57,6 +57,9 @@ func uploadHandler(c *gin.Context) { extraInfo.authdata.UserName = c.PostForm("auth_user") extraInfo.authdata.Password = c.PostForm("auth_pass") commandline := c.PostForm("commandline") + if commandline == "undefined" { + commandline = "" + } extraInfo.use_1200bps_touch, _ = strconv.ParseBool(c.PostForm("use_1200bps_touch")) extraInfo.wait_for_upload_port, _ = strconv.ParseBool(c.PostForm("wait_for_upload_port")) extraInfo.networkPort, _ = strconv.ParseBool(c.PostForm("network")) From b4e0d43af2a0305c6ae95dde3880543fa154bbf7 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Thu, 22 Oct 2015 17:51:42 +0200 Subject: [PATCH 02/31] remove outdated assembleCompilerCommand function --- programmer.go | 185 -------------------------------------------------- 1 file changed, 185 deletions(-) diff --git a/programmer.go b/programmer.go index 167b2e703..655f36af1 100644 --- a/programmer.go +++ b/programmer.go @@ -7,7 +7,6 @@ import ( "fmt" log "github.com/Sirupsen/logrus" "github.com/facchinm/go-serial" - "github.com/kardianos/osext" "github.com/mattn/go-shellwords" "io" "mime/multipart" @@ -389,187 +388,3 @@ func touch_port_1200bps(portname string, wait_for_upload_port bool) (string, err } return portname, nil } - -func assembleCompilerCommand(boardname string, portname string, filePath string) (bool, string, []string) { - - // get executable (self)path and use it as base for all other paths - execPath, _ := osext.Executable() - - boardFields := strings.Split(boardname, ":") - if len(boardFields) != 3 { - mapD := map[string]string{"Err": "Board need to be specified in core:architecture:name format"} - mapB, _ := json.Marshal(mapD) - h.broadcastSys <- mapB - return false, "", nil - } - tempPath := (filepath.Dir(execPath) + "/" + boardFields[0] + "/hardware/" + boardFields[1] + "/boards.txt") - file, err := os.Open(tempPath) - if err != nil { - mapD := map[string]string{"Err": "Could not find board: " + boardname} - mapB, _ := json.Marshal(mapD) - h.broadcastSys <- mapB - log.Println("Error:", err) - return false, "", nil - } - scanner := bufio.NewScanner(file) - - boardOptions := make(map[string]string) - uploadOptions := make(map[string]string) - - for scanner.Scan() { - // map everything matching with boardname - if strings.Contains(scanner.Text(), boardFields[2]) { - arr := strings.Split(scanner.Text(), "=") - arr[0] = strings.Replace(arr[0], boardFields[2]+".", "", 1) - boardOptions[arr[0]] = arr[1] - } - } - - if len(boardOptions) == 0 { - mapD := map[string]string{"Err": "Board " + boardFields[2] + " is not part of " + boardFields[0] + ":" + boardFields[1]} - mapB, _ := json.Marshal(mapD) - h.broadcastSys <- mapB - return false, "", nil - } - - // filepath need special care; the project_name var is the filename minus its extension (hex or bin) - // if we are going to modify standard IDE files we also could pass ALL filename - filePath = strings.Trim(filePath, "\n") - boardOptions["build.path"] = filepath.Dir(filePath) - boardOptions["build.project_name"] = strings.TrimSuffix(filepath.Base(filePath), filepath.Ext(filepath.Base(filePath))) - - file.Close() - - // get infos about the programmer - tempPath = (filepath.Dir(execPath) + "/" + boardFields[0] + "/hardware/" + boardFields[1] + "/platform.txt") - file, err = os.Open(tempPath) - if err != nil { - mapD := map[string]string{"Err": "Could not find board: " + boardname} - mapB, _ := json.Marshal(mapD) - h.broadcastSys <- mapB - log.Println("Error:", err) - return false, "", nil - } - scanner = bufio.NewScanner(file) - - tool := boardOptions["upload.tool"] - - for scanner.Scan() { - // map everything matching with upload - if strings.Contains(scanner.Text(), tool) { - arr := strings.Split(scanner.Text(), "=") - uploadOptions[arr[0]] = arr[1] - arr[0] = strings.Replace(arr[0], "tools."+tool+".", "", 1) - boardOptions[arr[0]] = arr[1] - // we have a "=" in command line - if len(arr) > 2 { - boardOptions[arr[0]] = arr[1] + "=" + arr[2] - } - } - } - file.Close() - - // multiple verisons of the same programmer can be handled if "version" is specified - version := uploadOptions["runtime.tools."+tool+".version"] - path := (filepath.Dir(execPath) + "/" + boardFields[0] + "/tools/" + tool + "/" + version) - if err != nil { - mapD := map[string]string{"Err": "Could not find board: " + boardname} - mapB, _ := json.Marshal(mapD) - h.broadcastSys <- mapB - log.Println("Error:", err) - return false, "", nil - } - - boardOptions["runtime.tools."+tool+".path"] = path - - cmdline := boardOptions["upload.pattern"] - // remove cmd.path as it is handled differently - cmdline = strings.Replace(cmdline, "\"{cmd.path}\"", " ", 1) - cmdline = strings.Replace(cmdline, "\"{path}/{cmd}\"", " ", 1) - cmdline = strings.Replace(cmdline, "\"", "", -1) - - initialPortName := portname - - // some boards (eg. Leonardo, Yun) need a special procedure to enter bootloader - if boardOptions["upload.use_1200bps_touch"] == "true" { - // triggers bootloader mode - // the portname could change in this occasion (expecially on Windows) so change portname - // with the port which will reappear - log.Println("Restarting in bootloader mode") - - mode := &serial.Mode{ - BaudRate: 1200, - Vmin: 1, - Vtimeout: 0, - } - port, err := serial.OpenPort(portname, mode) - if err != nil { - log.Println(err) - return false, "", nil - } - //port.SetDTR(false) - port.Close() - time.Sleep(time.Second / 2.0) - - timeout := false - go func() { - time.Sleep(2 * time.Second) - timeout = true - }() - - // time.Sleep(time.Second / 4) - // wait for port to reappear - if boardOptions["upload.wait_for_upload_port"] == "true" { - after_reset_ports, _ := serial.GetPortsList() - log.Println(after_reset_ports) - var ports []string - for { - ports, _ = serial.GetPortsList() - log.Println(ports) - time.Sleep(time.Millisecond * 200) - portname = findNewPortName(ports, after_reset_ports) - if portname != "" { - break - } - if timeout { - break - } - } - } - } - - if portname == "" { - portname = initialPortName - } - - boardOptions["serial.port"] = portname - boardOptions["serial.port.file"] = filepath.Base(portname) - - // split the commandline in substrings and recursively replace mapped strings - cmdlineSlice := strings.Split(cmdline, " ") - var winded = true - for index, _ := range cmdlineSlice { - winded = true - for winded != false { - cmdlineSlice[index], winded = formatCmdline(cmdlineSlice[index], boardOptions) - } - } - - tool = (filepath.Dir(execPath) + "/" + boardFields[0] + "/tools/" + tool + "/bin/" + tool) - // the file doesn't exist, we are on windows - if _, err := os.Stat(tool); err != nil { - tool = tool + ".exe" - // convert all "/" to "\" - tool = strings.Replace(tool, "/", "\\", -1) - } - - // remove blanks from cmdlineSlice - var cmdlineSliceOut []string - for _, element := range cmdlineSlice { - if element != "" { - cmdlineSliceOut = append(cmdlineSliceOut, element) - } - } - - return (tool != ""), tool, cmdlineSliceOut -} From 391a2d3b5beffdc2673cae26fa585396c2545108 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Thu, 22 Oct 2015 17:52:11 +0200 Subject: [PATCH 03/31] rework network programming and add ssh ability --- conn.go | 6 +- programmer.go | 167 ++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 125 insertions(+), 48 deletions(-) diff --git a/conn.go b/conn.go index 45354f743..f8285633a 100644 --- a/conn.go +++ b/conn.go @@ -81,7 +81,11 @@ func uploadHandler(c *gin.Context) { c.String(http.StatusBadRequest, err.Error()) } - go spProgramRW(port, board, board_rewrite, path, commandline, extraInfo) + if board_rewrite != "" { + board = board_rewrite + } + + go spProgramRW(port, board, path, commandline, extraInfo) } } diff --git a/programmer.go b/programmer.go index 655f36af1..ae7e9ec3c 100644 --- a/programmer.go +++ b/programmer.go @@ -8,6 +8,7 @@ import ( log "github.com/Sirupsen/logrus" "github.com/facchinm/go-serial" "github.com/mattn/go-shellwords" + "github.com/sfreiberg/simplessh" "io" "mime/multipart" "net/http" @@ -40,11 +41,105 @@ type boardExtraInfo struct { authdata basicAuthData } +// Scp uploads sourceFile to remote machine like native scp console app. +func Scp(client *simplessh.Client, sourceFile, targetFile string) error { + + session, err := client.SSHClient.NewSession() + if err != nil { + return err + } + defer session.Close() + + src, srcErr := os.Open(sourceFile) + + if srcErr != nil { + return srcErr + } + + srcStat, statErr := src.Stat() + + if statErr != nil { + return statErr + } + + go func() { + w, _ := session.StdinPipe() + + fmt.Fprintln(w, "C0644", srcStat.Size(), filepath.Base(targetFile)) + + if srcStat.Size() > 0 { + io.Copy(w, src) + fmt.Fprint(w, "\x00") + w.Close() + } else { + fmt.Fprint(w, "\x00") + w.Close() + } + + }() + + if err := session.Run("scp -t " + targetFile); err != nil { + return err + } + + return nil +} + +func spProgramSSHNetwork(portname string, boardname string, filePath string, commandline string, authdata basicAuthData) error { + log.Println("Starting network upload") + log.Println("Board Name: " + boardname) + + if authdata.UserName == "" { + authdata.UserName = "root" + } + + if authdata.Password == "" { + authdata.Password = "arduino" + } + + ssh_client, err := simplessh.ConnectWithPassword(portname+":22", authdata.UserName, authdata.Password) + if err != nil { + log.Println("Error connecting via ssh") + return err + } + defer ssh_client.Close() + + err = Scp(ssh_client, filePath, "/tmp/sketch"+filepath.Ext(filePath)) + if err != nil { + log.Printf("Upload: %s\n", err) + return err + } + + if commandline == "" { + // very special case for Yun (remove once AVR boards.txt is fixed) + commandline = "merge-sketch-with-bootloader.lua /tmp/sketch.hex && /usr/bin/run-avrdude /tmp/sketch.hex" + } + + fmt.Println(commandline) + + ssh_output, err := ssh_client.Exec(commandline) + if err == nil { + log.Printf("Flash: %s\n", ssh_output) + mapD := map[string]string{"ProgrammerStatus": "Busy", "Msg": string(ssh_output)} + mapB, _ := json.Marshal(mapD) + h.broadcastSys <- mapB + } + return err +} + func spProgramNetwork(portname string, boardname string, filePath string, authdata basicAuthData) error { log.Println("Starting network upload") log.Println("Board Name: " + boardname) + if authdata.UserName == "" { + authdata.UserName = "root" + } + + if authdata.Password == "" { + authdata.Password = "arduino" + } + // Prepare a form that you will submit to that URL. _url := "http://" + portname + "/data/upload_sketch_silent" var b bytes.Buffer @@ -109,23 +204,10 @@ func spProgramNetwork(portname string, boardname string, filePath string, authda log.Errorf("bad status: %s", res.Status) err = fmt.Errorf("bad status: %s", res.Status) } - - if err != nil { - log.Printf("Command finished with error: %v ", err) - mapD := map[string]string{"ProgrammerStatus": "Error", "Msg": "Could not program the board", "Output": "", "Err": "Could not program the board"} - mapB, _ := json.Marshal(mapD) - h.broadcastSys <- mapB - } else { - log.Printf("Finished without error. Good stuff.") - mapD := map[string]string{"ProgrammerStatus": "Done", "Flash": "Ok", "Output": ""} - mapB, _ := json.Marshal(mapD) - h.broadcastSys <- mapB - // analyze stdin - } return err } -func spProgramLocal(portname string, boardname string, filePath string, commandline string, extraInfo boardExtraInfo) { +func spProgramLocal(portname string, boardname string, filePath string, commandline string, extraInfo boardExtraInfo) error { var err error if extraInfo.use_1200bps_touch { @@ -134,7 +216,7 @@ func spProgramLocal(portname string, boardname string, filePath string, commandl if err != nil { log.Println("Could not touch the port") - return + return err } log.Printf("Received commandline (unresolved):" + commandline) @@ -155,15 +237,10 @@ func spProgramLocal(portname string, boardname string, filePath string, commandl } z, _ := shellwords.Parse(commandline) - spHandlerProgram(z[0], z[1:]) -} - -func spProgram(portname string, boardname string, filePath string, commandline string, extraInfo boardExtraInfo) { - - spProgramRW(portname, boardname, "", filePath, commandline, extraInfo) + return spHandlerProgram(z[0], z[1:]) } -func spProgramRW(portname string, boardname string, boardname_rewrite string, filePath string, commandline string, extraInfo boardExtraInfo) { +func spProgramRW(portname string, boardname string, filePath string, commandline string, extraInfo boardExtraInfo) { compiling = true defer func() { @@ -174,24 +251,32 @@ func spProgramRW(portname string, boardname string, boardname_rewrite string, fi var err error if extraInfo.networkPort { - if boardname_rewrite != "" { - err = spProgramNetwork(portname, boardname_rewrite, filePath, extraInfo.authdata) - } else { - err = spProgramNetwork(portname, boardname, filePath, extraInfo.authdata) - } + err = spProgramNetwork(portname, boardname, filePath, extraInfo.authdata) if err != nil { - mapD := map[string]string{"ProgrammerStatus": "Error", "Msg": "Could not program the board", "Output": "", "Err": err.Error()} - mapB, _ := json.Marshal(mapD) - h.broadcastSys <- mapB + // no http method available, try ssh upload + err = spProgramSSHNetwork(portname, boardname, filePath, commandline, extraInfo.authdata) } } else { - spProgramLocal(portname, boardname, filePath, commandline, extraInfo) + err = spProgramLocal(portname, boardname, filePath, commandline, extraInfo) + } + + if err != nil { + log.Printf("Command finished with error: %v", err) + mapD := map[string]string{"ProgrammerStatus": "Error", "Msg": "Could not program the board"} + mapB, _ := json.Marshal(mapD) + h.broadcastSys <- mapB + } else { + log.Printf("Finished without error. Good stuff") + mapD := map[string]string{"ProgrammerStatus": "Done", "Flash": "Ok"} + mapB, _ := json.Marshal(mapD) + h.broadcastSys <- mapB + // analyze stdin } } var oscmd *exec.Cmd -func spHandlerProgram(flasher string, cmdString []string) { +func spHandlerProgram(flasher string, cmdString []string) error { // if runtime.GOOS == "darwin" { // sh, _ := exec.LookPath("sh") @@ -218,12 +303,12 @@ func spHandlerProgram(flasher string, cmdString []string) { stdout, err := oscmd.StdoutPipe() if err != nil { - return + return err } stderr, err := oscmd.StderrPipe() if err != nil { - return + return err } multi := io.MultiReader(stderr, stdout) @@ -252,19 +337,7 @@ func spHandlerProgram(flasher string, cmdString []string) { err = oscmd.Wait() - if err != nil { - log.Printf("Command finished with error: %v", err) - mapD := map[string]string{"ProgrammerStatus": "Error", "Msg": "Could not program the board"} - mapB, _ := json.Marshal(mapD) - h.broadcastSys <- mapB - } else { - log.Printf("Finished without error. Good stuff") - mapD := map[string]string{"ProgrammerStatus": "Done", "Flash": "Ok"} - mapB, _ := json.Marshal(mapD) - h.broadcastSys <- mapB - // analyze stdin - - } + return err } func spHandlerProgramKill() { From 29c6b4e9ed42cd8f6e841a4afcf564be972d4dc2 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Fri, 23 Oct 2015 11:52:57 +0200 Subject: [PATCH 04/31] add OS field to reported infos --- hub.go | 1 + 1 file changed, 1 insertion(+) diff --git a/hub.go b/hub.go index 421989701..04a0d5289 100755 --- a/hub.go +++ b/hub.go @@ -57,6 +57,7 @@ func (h *hub) run() { c.send <- []byte("{\"Version\" : \"" + version + "\"} ") c.send <- []byte("{\"Commands\" : [\"list\", \"open [portName] [baud] [bufferAlgorithm (optional)]\", \"send [portName] [cmd]\", \"sendnobuf [portName] [cmd]\", \"close [portName]\", \"bufferalgorithms\", \"baudrates\", \"restart\", \"exit\", \"program [portName] [board:name] [$path/to/filename/without/extension]\", \"programfromurl [portName] [board:name] [urlToHexFile]\"]} ") c.send <- []byte("{\"Hostname\" : \"" + *hostname + "\"} ") + c.send <- []byte("{\"OS\" : \"" + runtime.GOOS + "\"} ") case c := <-h.unregister: delete(h.connections, c) // put close in func cuz it was creating panics and want From 15c10832ee36c20efc441df189faf34fc65f0152 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Fri, 23 Oct 2015 11:53:44 +0200 Subject: [PATCH 05/31] slightly rework multiWriter log --- hub.go | 3 +-- main.go | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/hub.go b/hub.go index 04a0d5289..b03ec0a75 100755 --- a/hub.go +++ b/hub.go @@ -217,11 +217,10 @@ func checkCmd(m []byte) { //log.Print("Done with checkCmd") } -var multi_writer = io.MultiWriter(&logger_ws, os.Stderr) - func logAction(sl string) { if strings.HasPrefix(sl, "log on") { *logDump = "on" + multi_writer := io.MultiWriter(&logger_ws, os.Stderr) log.SetOutput(multi_writer) } else if strings.HasPrefix(sl, "log off") { *logDump = "off" diff --git a/main.go b/main.go index 99391714d..87a644dbd 100755 --- a/main.go +++ b/main.go @@ -53,7 +53,7 @@ type logWriter struct{} func (u *logWriter) Write(p []byte) (n int, err error) { h.broadcastSys <- p - return 0, nil + return len(p), nil } var logger_ws logWriter @@ -270,7 +270,7 @@ const homeTemplateHtml = ` var log = document.getElementById('log'); var pause = document.getElementById('myCheck'); var messages = []; - var only_log = false; + var only_log = true; function appendLog(msg) { From b84138f4728af01fa6f527deec54cf3ac15bf17b Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Fri, 23 Oct 2015 11:54:39 +0200 Subject: [PATCH 06/31] drop flasher extension Windows is smart enough to add trailing .exe, so we'll be able to add different commandlines depending on host OS --- programmer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programmer.go b/programmer.go index ae7e9ec3c..ee3c680bf 100644 --- a/programmer.go +++ b/programmer.go @@ -297,7 +297,7 @@ func spHandlerProgram(flasher string, cmdString []string) error { extension = ".exe" } - oscmd = exec.Command(flasher+extension, cmdString...) + oscmd = exec.Command(flasher, cmdString...) tellCommandNotToSpawnShell(oscmd) From a58dca9eac23c2fd1dd342ae1ad5ca5dc656d6c0 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Fri, 23 Oct 2015 11:56:03 +0200 Subject: [PATCH 07/31] rework port disappear/reappear for 1200bps_touch this should solve problems with slower (or Win based) systems --- programmer.go | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/programmer.go b/programmer.go index ee3c680bf..8d4a5b04f 100644 --- a/programmer.go +++ b/programmer.go @@ -413,6 +413,11 @@ func touch_port_1200bps(portname string, wait_for_upload_port bool) (string, err initialPortName := portname log.Println("Restarting in bootloader mode") + before_reset_ports, _ := serial.GetPortsList() + log.Println(before_reset_ports) + + var ports []string + mode := &serial.Mode{ BaudRate: 1200, Vmin: 0, @@ -428,24 +433,36 @@ func touch_port_1200bps(portname string, wait_for_upload_port bool) (string, err log.Println(err) } port.Close() - time.Sleep(time.Second / 2.0) timeout := false go func() { - time.Sleep(2 * time.Second) + time.Sleep(10 * time.Second) timeout = true }() - // time.Sleep(time.Second / 4) + // wait for port to disappear + if wait_for_upload_port { + for { + ports, _ = serial.GetPortsList() + log.Println(ports) + portname = findNewPortName(ports, before_reset_ports) + if portname != "" { + break + } + if timeout { + break + } + time.Sleep(time.Millisecond * 100) + } + } + // wait for port to reappear if wait_for_upload_port { after_reset_ports, _ := serial.GetPortsList() log.Println(after_reset_ports) - var ports []string for { ports, _ = serial.GetPortsList() log.Println(ports) - time.Sleep(time.Millisecond * 200) portname = findNewPortName(ports, after_reset_ports) if portname != "" { break @@ -453,6 +470,7 @@ func touch_port_1200bps(portname string, wait_for_upload_port bool) (string, err if timeout { break } + time.Sleep(time.Millisecond * 100) } } From 8494054c11a0c2f6e0917c501e7831ff1b23efd3 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Fri, 13 Nov 2015 13:11:54 +0100 Subject: [PATCH 08/31] add configurable CORS allowed origins --- config.ini | 1 + main.go | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/config.ini b/config.ini index f0639f2c6..dae4bce0e 100644 --- a/config.ini +++ b/config.ini @@ -7,3 +7,4 @@ v = true # show debug logging appName = CreateBridge updateUrl = http://downloads.arduino.cc/ #updateUrl = http://localhost/ +origins = http://webide.arduino.cc:8080 \ No newline at end of file diff --git a/main.go b/main.go index 87a644dbd..c92bfe525 100755 --- a/main.go +++ b/main.go @@ -43,6 +43,7 @@ var ( tempToolsPath = createToolsDir() port string portSSL string + origins = flag.String("origins", "", "Allowed origin list for CORS") ) type NullWriter int @@ -109,6 +110,20 @@ func main() { iniflags.Parse() } + // move CORS to config file compatibility, Vagrant version + if *origins == "" { + log.Println("Patching config.ini for compatibility") + f, err := os.OpenFile(dest+"/"+*configIni, os.O_APPEND|os.O_WRONLY, 0666) + if err != nil { + panic(err) + } + _, err = f.WriteString("\norigins = http://webide.arduino.cc:8080\n") + if err != nil { + panic(err) + } + f.Close() + restart("") + } //log.SetFormatter(&log.JSONFormatter{}) log.SetLevel(log.InfoLevel) @@ -194,8 +209,14 @@ func main() { socketHandler := wsHandler().ServeHTTP + extraOriginStr := "https://create.arduino.cc, http://create.arduino.cc, https://create-dev.arduino.cc, http://create-dev.arduino.cc, http://create-staging.arduino.cc, https://create-staging.arduino.cc," + + for i := 8990; i < 9001; i++ { + extraOriginStr = extraOriginStr + " http://localhost:" + strconv.Itoa(i) + ", https://localhost:" + strconv.Itoa(i) + } + r.Use(cors.Middleware(cors.Config{ - Origins: "https://create.arduino.cc, http://create.arduino.cc, https://create-dev.arduino.cc, http://create-dev.arduino.cc, http://webide.arduino.cc:8080, http://create-staging.arduino.cc, https://create-staging.arduino.cc, http://localhost:8989, https://localhost:8990", + Origins: *origins + "," + extraOriginStr, Methods: "GET, PUT, POST, DELETE", RequestHeaders: "Origin, Authorization, Content-Type", ExposedHeaders: "", From e68ccb44c1c85902fbd649ffe40a4bd4c5b17e11 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Mon, 23 Nov 2015 11:29:43 +0100 Subject: [PATCH 09/31] add certificate in Windows format --- compile_webidebridge.sh | 4 ++-- fakecerts/cert.cer | Bin 0 -> 776 bytes 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 fakecerts/cert.cer diff --git a/compile_webidebridge.sh b/compile_webidebridge.sh index f9a5c8639..a66a3f8be 100755 --- a/compile_webidebridge.sh +++ b/compile_webidebridge.sh @@ -29,10 +29,10 @@ createZipEmbeddableFileArduino() mkdir arduino/arduino cp -r arduino/hardware arduino/tools\_$GOOS\_$GOARCH arduino/boards.json arduino/arduino cp config.ini arduino - cp fakecerts/*.pem arduino/ + cp fakecerts/*.pem fakecerts/*.cer arduino/ mv arduino/arduino/tools* arduino/arduino/tools cd arduino - zip -r arduino.zip config.ini *.pem > /dev/null + zip -r arduino.zip config.ini *.pem *.cer > /dev/null cd .. #cat arduino/arduino.zip >> $3 #zip --adjust-sfx $3 diff --git a/fakecerts/cert.cer b/fakecerts/cert.cer new file mode 100644 index 0000000000000000000000000000000000000000..2e62ff04dce1b254151ffeba5ac651eb31842960 GIT binary patch literal 776 zcmXqLVrDUDVtm8I$?#Y2tH`NM6XOkd**LY@JlekVGBUEVG8niRavN~6F^96S2{VNT z8;TeRfjC^k+>S*lrI~s83O+v0FeTi=Or9ZzLIwgLCCtK{Ir+(nIT`uIB?fZhyoRO* zW`>3a=0>K*W>G+{8IWrL=QFZ0FgG#sGXQx+34 z8v@S0-0pttw8Ed-@3o6g=$UdVh!va^n5ui;xWFgnjje>fmXn8EPpa@in~i@%tM( zcbZuy8mo8R-zz(x-z>-_Rp-cVvDc25M4#8Pe>i=7sTb2E&GS2cul{b>dg_qS)z>S+ z)y`_Ah8Ih2y2yCg^z+=3+DWVnonLZ2+IhIcFs~t`;!VYV7v?4|t(SW~Y&zVr_}=ac z?d#cR=h@8F30!W*zhSE7^}y%r;+W-4!zS}CV)}5A;aAE8;{^&Ybe6Sdt*rj8mED)f z#LURRh#W$|2nL1_BZI*7S~l<2CJT1g`lf#JER_P<;X4KsXym>zU?KCxzd3j0X*|&U3xxU?f=I7C2nkm4SB_jWWGNr zy?_4J$N3xOp1Cf$8#7_Y`pYM{D~(`eO8G^xsZ^@Rc6MJu;0ZVnk(#9 cJQbXCe}a^LRB<_f)zsS$R{d}|za;zx0GZq=+5i9m literal 0 HcmV?d00001 From e6ba498e0028cee028fdb2ba0ede3de34e945777 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Thu, 26 Nov 2015 15:33:23 +0100 Subject: [PATCH 10/31] add createCerts commandline switch will be used during installation to trigger a new certificate creation --- certificates.go | 156 +++++++++++++++++++++++++++++++++++++++++++++ fakecerts/cert.cer | Bin 776 -> 0 bytes fakecerts/cert.pem | 19 ------ fakecerts/key.pem | 27 -------- main.go | 11 ++++ 5 files changed, 167 insertions(+), 46 deletions(-) create mode 100644 certificates.go delete mode 100644 fakecerts/cert.cer delete mode 100644 fakecerts/cert.pem delete mode 100644 fakecerts/key.pem diff --git a/certificates.go b/certificates.go new file mode 100644 index 000000000..a1451b959 --- /dev/null +++ b/certificates.go @@ -0,0 +1,156 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Generate a self-signed X.509 certificate for a TLS server. Outputs to +// 'cert.pem' and 'key.pem' and will overwrite existing files. + +package main + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "fmt" + log "github.com/Sirupsen/logrus" + "io/ioutil" + "math/big" + "net" + "os" + "strings" + "time" +) + +var ( + host = "localhost" + validFrom = "" + validFor = 365 * 24 * time.Hour * 2 // 2 years + isCA = true + rsaBits = 2048 + ecdsaCurve = "" +) + +func publicKey(priv interface{}) interface{} { + switch k := priv.(type) { + case *rsa.PrivateKey: + return &k.PublicKey + case *ecdsa.PrivateKey: + return &k.PublicKey + default: + return nil + } +} + +func pemBlockForKey(priv interface{}) *pem.Block { + switch k := priv.(type) { + case *rsa.PrivateKey: + return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)} + case *ecdsa.PrivateKey: + b, err := x509.MarshalECPrivateKey(k) + if err != nil { + fmt.Fprintf(os.Stderr, "Unable to marshal ECDSA private key: %v", err) + os.Exit(2) + } + return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b} + default: + return nil + } +} + +func generateCertificates() { + + var priv interface{} + var err error + switch ecdsaCurve { + case "": + priv, err = rsa.GenerateKey(rand.Reader, rsaBits) + case "P224": + priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader) + case "P256": + priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + case "P384": + priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader) + case "P521": + priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader) + default: + fmt.Fprintf(os.Stderr, "Unrecognized elliptic curve: %q", ecdsaCurve) + os.Exit(1) + } + if err != nil { + log.Fatalf("failed to generate private key: %s", err) + } + + var notBefore time.Time + if len(validFrom) == 0 { + notBefore = time.Now() + } else { + notBefore, err = time.Parse("Jan 2 15:04:05 2006", validFrom) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to parse creation date: %s\n", err) + os.Exit(1) + } + } + + notAfter := notBefore.Add(validFor) + + serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) + serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) + if err != nil { + log.Fatalf("failed to generate serial number: %s", err) + } + + template := x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{ + Organization: []string{"Arduino LLC US"}, + }, + NotBefore: notBefore, + NotAfter: notAfter, + + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + BasicConstraintsValid: true, + } + + hosts := strings.Split(host, ",") + for _, h := range hosts { + if ip := net.ParseIP(h); ip != nil { + template.IPAddresses = append(template.IPAddresses, ip) + } else { + template.DNSNames = append(template.DNSNames, h) + } + } + + if isCA { + template.IsCA = true + template.KeyUsage |= x509.KeyUsageCertSign + } + + derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv) + if err != nil { + log.Fatalf("Failed to create certificate: %s", err) + } + + certOut, err := os.Create("cert.pem") + if err != nil { + log.Fatalf("failed to open cert.pem for writing: %s", err) + } + pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) + certOut.Close() + log.Print("written cert.pem\n") + + ioutil.WriteFile("cert.cer", derBytes, 0644) + + keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + if err != nil { + log.Print("failed to open key.pem for writing:", err) + return + } + pem.Encode(keyOut, pemBlockForKey(priv)) + keyOut.Close() + log.Print("written key.pem\n") +} diff --git a/fakecerts/cert.cer b/fakecerts/cert.cer deleted file mode 100644 index 2e62ff04dce1b254151ffeba5ac651eb31842960..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 776 zcmXqLVrDUDVtm8I$?#Y2tH`NM6XOkd**LY@JlekVGBUEVG8niRavN~6F^96S2{VNT z8;TeRfjC^k+>S*lrI~s83O+v0FeTi=Or9ZzLIwgLCCtK{Ir+(nIT`uIB?fZhyoRO* zW`>3a=0>K*W>G+{8IWrL=QFZ0FgG#sGXQx+34 z8v@S0-0pttw8Ed-@3o6g=$UdVh!va^n5ui;xWFgnjje>fmXn8EPpa@in~i@%tM( zcbZuy8mo8R-zz(x-z>-_Rp-cVvDc25M4#8Pe>i=7sTb2E&GS2cul{b>dg_qS)z>S+ z)y`_Ah8Ih2y2yCg^z+=3+DWVnonLZ2+IhIcFs~t`;!VYV7v?4|t(SW~Y&zVr_}=ac z?d#cR=h@8F30!W*zhSE7^}y%r;+W-4!zS}CV)}5A;aAE8;{^&Ybe6Sdt*rj8mED)f z#LURRh#W$|2nL1_BZI*7S~l<2CJT1g`lf#JER_P<;X4KsXym>zU?KCxzd3j0X*|&U3xxU?f=I7C2nkm4SB_jWWGNr zy?_4J$N3xOp1Cf$8#7_Y`pYM{D~(`eO8G^xsZ^@Rc6MJu;0ZVnk(#9 cJQbXCe}a^LRB<_f)zsS$R{d}|za;zx0GZq=+5i9m diff --git a/fakecerts/cert.pem b/fakecerts/cert.pem deleted file mode 100644 index 7f648b91c..000000000 --- a/fakecerts/cert.pem +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDBDCCAewCCQD9LvUUyrKRXzANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJV -UzEUMBIGA1UEChMLQXJkdWlubyBMTEMxCzAJBgNVBAsTAklUMRIwEAYDVQQDEwls -b2NhbGhvc3QwHhcNMTUwNjExMDcyNTM2WhcNMTYwNjEwMDcyNTM2WjBEMQswCQYD -VQQGEwJVUzEUMBIGA1UEChMLQXJkdWlubyBMTEMxCzAJBgNVBAsTAklUMRIwEAYD -VQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7 -3UTunwOvcw1hgFDN6bdHxssg/H33faLILjUJIBZwyRCVLc8zcExk7D0YLxnMBaxs -t4DoPfMlAXiJ+GT3fiOaYTKHmGT3Qz85WC6Yngz9A/usDQSSYe9rI4k3oLNA4F+b -6VU5FBj1V3nj79gs3IMEkTMnit+9HZ8PNlJEZSzEuxbrQdIV530H8MvHpUoCkinP -uPur9zGFysIS1euoVybNKmVXcxmy0QHDNfOddH2SBaFD6QriucOIMW6AVHjseL9E -A4IKKum88LLDiKPeu3gr12vNnjydLFGnNg+wlTnXUeeuXgMfNVaTDaIC8NEA+mSQ -M6Ag6CymhWqpe/cqa45hAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBABCXfQZLhYI4 -B0VjgwDDRohTAhsSyaQvFEhGOx2Oo28RhKgY2xRtfjDlm7IzTLga4ApsHqIMf85F -z4bpDDciwPhQDJ6a0ueXJv+xb6RGBnGAbnOiHPfgdd/P2vGfsR7mRaTdXJC4r9PI -C3kzjwTlplaulLbHs5XIXImGvAvRX5sPmkqlBAQs8PVG4I71pKXo1M4kl7uzr96+ -+DKnVz2oACAPCW6zTlT/MlBH4nSeCQfGiE8iWAqODviONOQjFnaTKLw6d1YnbnLp -1gokB8sk1TAM3qjb6giZpe945xISSNUDAVRW+3NIKag+qOURnN+QGi9ac3cPepXb -4Kr4QM+kV+g= ------END CERTIFICATE----- diff --git a/fakecerts/key.pem b/fakecerts/key.pem deleted file mode 100644 index 26c54a281..000000000 --- a/fakecerts/key.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEogIBAAKCAQEAu91E7p8Dr3MNYYBQzem3R8bLIPx9932iyC41CSAWcMkQlS3P -M3BMZOw9GC8ZzAWsbLeA6D3zJQF4ifhk934jmmEyh5hk90M/OVgumJ4M/QP7rA0E -kmHvayOJN6CzQOBfm+lVORQY9Vd54+/YLNyDBJEzJ4rfvR2fDzZSRGUsxLsW60HS -Fed9B/DLx6VKApIpz7j7q/cxhcrCEtXrqFcmzSplV3MZstEBwzXznXR9kgWhQ+kK -4rnDiDFugFR47Hi/RAOCCirpvPCyw4ij3rt4K9drzZ48nSxRpzYPsJU511Hnrl4D -HzVWkw2iAvDRAPpkkDOgIOgspoVqqXv3KmuOYQIDAQABAoIBADzL4df7W/z2ldj8 -5qmMvkSbP/d/3uAuJ3TzBzTZzolXeGdeuNRjvkVW8nqWG5ocJ+3TAQOnsL1EGZdE -7J/vkWQPmoOpPNuMRrSvJf08AOYM2PCYEeexjAK3MFvxRLF1K1vQikT7jQww8ABl -CSeTgU8EEnL0jW2tXWFV6g+6Ul+jwfq5IvbUpMsMOPuUEQy85rm04bCw/vUnhZXk -gFSpAp5mKPI6J/v2fkJTjgxi0wURxHKFdH/dFr69k9G7Vv9L8meiZYwA0QsYcmeJ -EAGpZHQXpTCmmmzWM85vz9vg4qUBwF8ypXcWjuqfjAopXvuenyIkfa9paDriRnNM -A3JmUQECgYEA66fdY8cU1cJw5jmhc10mi6lDz0Xswba4kaYnb2fwr7tlkBFzYYVn -GY6f2fNxdx8ZpOCYzembJ67qCXODw4LLle1slgHzOWHQ4RJd2EDw/i9woPHGsT3a -TIk0tX3wOjtJJEXNzQEiqcDqGqrpY3pnm4lFGR4RSE6vIYfPwyO9y7ECgYEAzBUv -hKy19GSFK8tkYa/WcmNMCGwLJB0pEMuT3heDjSEKYNaTh8YcIpeEY3aCWbMKxWdu -O5TIouyNJHtm4Q0umG08ZGekLTZy22it2UJabROvHVHeSnPki9a12Uc3KgB6mBzb -nnHXQ8hR60o0GTPMudVW12aZh9gy+EcGWQEwibECgYAIdQ3M9ugYg9HpcUgKC93G -RVzZo3jLuvMExyHDLcfFhsQuV3H8nf0FPcke2U3JKKSS9jyFp0yaL/zWOf8QlTEZ -QFwVRhykgo4shaw4hpwfgzRXklW/Jqke9g2eNdbZQCdv1dF8+f10eifsrRWTLGFr -g5GnRRz5q1k9qtIZ/r5hAQKBgCegMXLMaiQC5IylWF9TWgsp1piICf3AH7ogHRzx -adycPrygzVJ+l/Xrf4wkdZjfF8dOluvArthbn+gmgcpO2e5Ev4YrTYht2w1ZHPBj -XtVxDf5eaBACwqyYSwTePArOvv8ME2SHbCnAGo/Z/5WpJiYrE0qNpF/pDbSBbe0Y -OwlxAoGAdPEjpeeCpyUcoJMVnIxM7AtsOqomd0lBrRgRq05FYvGMAygoKzz+OBp+ -VgptcGJp+6t5MY9R3asRaFp3rOcXvX5R4wBMfijlzoezMEFZN/+xpm7LN2E0domO -xyku5Kcn9G/KTxCduepOtjqoNYkKYAcrdkmRfZ9C9xvuB2lKjk8= ------END RSA PRIVATE KEY----- diff --git a/main.go b/main.go index 87a644dbd..49d4efc55 100755 --- a/main.go +++ b/main.go @@ -39,6 +39,7 @@ var ( hostname = flag.String("hostname", "unknown-hostname", "Override the hostname we get from the OS") updateUrl = flag.String("updateUrl", "", "") appName = flag.String("appName", "", "") + genCert = flag.Bool("generateCert", false, "") globalToolsMap = make(map[string]string) tempToolsPath = createToolsDir() port string @@ -77,6 +78,11 @@ func main() { flag.Parse() + if *genCert == true { + generateCertificates() + exit() + } + if *hibernate == false { go func() { @@ -212,6 +218,11 @@ func main() { r.Handle("WSS", "/socket.io/", socketHandler) r.GET("/info", infoHandler) go func() { + // check if certificates exist; if not, use plain http + if _, err := os.Stat(filepath.Join(dest, "cert.pem")); os.IsNotExist(err) { + return + } + start := 8990 end := 9000 i := start From aa45d8366a29a925ef3dda9aa1e77dd4cee6971e Mon Sep 17 00:00:00 2001 From: Matteo Suppo Date: Fri, 27 Nov 2015 12:51:12 +0100 Subject: [PATCH 11/31] Fix cors by adding the correct commas --- main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index c92bfe525..a95038a96 100755 --- a/main.go +++ b/main.go @@ -209,10 +209,10 @@ func main() { socketHandler := wsHandler().ServeHTTP - extraOriginStr := "https://create.arduino.cc, http://create.arduino.cc, https://create-dev.arduino.cc, http://create-dev.arduino.cc, http://create-staging.arduino.cc, https://create-staging.arduino.cc," + extraOriginStr := "https://create.arduino.cc, http://create.arduino.cc, https://create-dev.arduino.cc, http://create-dev.arduino.cc, http://create-staging.arduino.cc, https://create-staging.arduino.cc" for i := 8990; i < 9001; i++ { - extraOriginStr = extraOriginStr + " http://localhost:" + strconv.Itoa(i) + ", https://localhost:" + strconv.Itoa(i) + extraOriginStr = extraOriginStr + ", http://localhost:" + strconv.Itoa(i) + ", https://localhost:" + strconv.Itoa(i) } r.Use(cors.Middleware(cors.Config{ From 7e4bbc71f30bb1960263b5ef355caacc3217c466 Mon Sep 17 00:00:00 2001 From: Luca Cipriani Date: Fri, 27 Nov 2015 17:20:05 +0100 Subject: [PATCH 12/31] Be sure we have a comma + space separated list The one char fix @matteosuppo --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index a95038a96..8d0860a42 100755 --- a/main.go +++ b/main.go @@ -216,7 +216,7 @@ func main() { } r.Use(cors.Middleware(cors.Config{ - Origins: *origins + "," + extraOriginStr, + Origins: *origins + ", " + extraOriginStr, Methods: "GET, PUT, POST, DELETE", RequestHeaders: "Origin, Authorization, Content-Type", ExposedHeaders: "", From 3bb66ad58cae3db24b11a47db5902e09c4f3887d Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Mon, 30 Nov 2015 11:28:35 +0100 Subject: [PATCH 13/31] genCert: exit with proper error code --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index dd356ac51..88789bf5a 100755 --- a/main.go +++ b/main.go @@ -81,7 +81,7 @@ func main() { if *genCert == true { generateCertificates() - exit() + os.Exit(0) } if *hibernate == false { From cff4c8458c2d63498e4948f41a5393d7320b7d1c Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Mon, 30 Nov 2015 16:13:19 +0100 Subject: [PATCH 14/31] Update README.md --- README.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1c8921a25..9ca35fcee 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ arduino-create-agent ==================== -Version X.XX - Get the latest version of the Agent for all supported platforms: * [Windows](http://downloads.arduino.cc/CreateBridgeStable/ArduinoCreateAgent-1.1-windows-installer.exe) @@ -21,6 +19,16 @@ Please use the current latest version: * [MacOSX dev](http://downloads.arduino.cc/CreateBridge/staging/ArduinoCreateAgent-1.0-osx-installer.dmg) * [Linux x64 dev](http://downloads.arduino.cc/CreateBridge/staging/ArduinoCreateAgent-1.0-linux-x64-installer.run) +## Compiling + +`compile_webidebridge.sh` contains the cross-platform script we use to deploy the agent for all the supported platforms; it needs to be adjusted as per your `go` installation paths and OS. + +You can use `bootstrapPlatforms` function to compile the needed CGO-enabled environment + +Other prerequisites are: +* libappindicator (Linux only) +* [go-selfupdate] (https://github.com/sanbornm/go-selfupdate) if you want to test automatic updates + ## Submitting an issue Please attach the output of the commands running at the debug console if useful. From 6a12390d2625c84a205f51bc234a4137eec97e3b Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Tue, 1 Dec 2015 18:25:09 +0100 Subject: [PATCH 15/31] use a similarity map to try to resolve cmdline completely --- programmer.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/programmer.go b/programmer.go index 8d4a5b04f..e3bf5aa3b 100644 --- a/programmer.go +++ b/programmer.go @@ -9,6 +9,7 @@ import ( "github.com/facchinm/go-serial" "github.com/mattn/go-shellwords" "github.com/sfreiberg/simplessh" + "github.com/xrash/smetrics" "io" "mime/multipart" "net/http" @@ -233,6 +234,19 @@ func spProgramLocal(portname string, boardname string, filePath string, commandl fmt.Println(runtimeVars) for _, element := range runtimeVars { + + // use string similarity to resolve a runtime var with a "similar" map element + if globalToolsMap[element] == "" { + max_similarity := 0.0 + for i, candidate := range globalToolsMap { + similarity := smetrics.Jaro(element, i) + if similarity > 0.8 && similarity > max_similarity { + max_similarity = similarity + globalToolsMap[element] = candidate + } + } + } + commandline = strings.Replace(commandline, element, globalToolsMap[element], 1) } From af4189d1ba49078fbad5e6c74754f9888c9c73fc Mon Sep 17 00:00:00 2001 From: Matteo Suppo Date: Fri, 4 Dec 2015 14:28:50 +0100 Subject: [PATCH 16/31] Give the correct port for upload --- info.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/info.go b/info.go index 194d46e4c..6fe3df038 100644 --- a/info.go +++ b/info.go @@ -7,7 +7,7 @@ import ( func infoHandler(c *gin.Context) { c.JSON(200, gin.H{ "http": "http://localhost" + port, - "https": "https://localhost" + port, + "https": "https://localhost" + portSSL, "ws": "ws://localhost" + port, "wss": "wss://localhost" + portSSL, }) From 139b8e6763b0d3aa393d00fae5cd32285e7c1ac3 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Wed, 9 Dec 2015 13:16:31 +0100 Subject: [PATCH 17/31] update Godeps --- Godeps/Godeps.json | 93 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 70 insertions(+), 23 deletions(-) diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index e01712aa6..63c8cb347 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -2,6 +2,16 @@ "ImportPath": "github.com/arduino/arduino-create-agent", "GoVersion": "go1.4.2", "Deps": [ + { + "ImportPath": "github.com/Sirupsen/logrus", + "Comment": "v0.8.6-1-g8bca266", + "Rev": "8bca2664072173a3c71db4c28ca8d304079b1787" + }, + { + "ImportPath": "github.com/carlescere/scheduler", + "Comment": "0.1-11-gd39e4af", + "Rev": "d39e4af87bb89586f86db467fa203d353b5d34ff" + }, { "ImportPath": "github.com/facchinm/go-serial", "Rev": "3cfbd2fab741f7c9d238cb3bd17980110c81bd46" @@ -10,31 +20,35 @@ "ImportPath": "github.com/facchinm/systray", "Rev": "b32308b0b662e45cde7c5986bc29def5d48bafbb" }, + { + "ImportPath": "github.com/getlantern/filepersist", + "Rev": "e91ecdee50cac4a38975041089abdddcb94c4e97" + }, { "ImportPath": "github.com/getlantern/golog", "Rev": "5245e761fd1c8e9ccba87de802a0f666ed55980f" }, { "ImportPath": "github.com/gin-gonic/gin", - "Comment": "v1.0rc1-128-gfc5e355", - "Rev": "fc5e3557242901e24016d4474168515434871dd5" + "Comment": "v1.0rc1-136-gfd5d429", + "Rev": "fd5d4294a5d5223d55fc76d7840f4b0ad91647bb" }, { "ImportPath": "github.com/googollee/go-engine.io", - "Rev": "597faf3df88a01780a5881fafbcbccd9d5c3fab0" + "Rev": "5525e3de461352f4c88d28287161ca2272c024ac" }, { "ImportPath": "github.com/googollee/go-socket.io", - "Comment": "0.9.x-33-g9c83c02", - "Rev": "9c83c02fa6172eaea8252b6428e3cef3576c9746" + "Comment": "0.9.x-35-g647d8ca", + "Rev": "647d8cabbf6b58e48570e56cb59692cbc8fdb1d3" }, { "ImportPath": "github.com/gorilla/websocket", - "Rev": "a3ec486e6a7a41858210b0fc5d7b5df593b3c4a3" + "Rev": "2dbddebb8266b93c5e6b119efb54e89043186f3f" }, { "ImportPath": "github.com/inconshreveable/go-update", - "Rev": "68f5725818189545231c1fd8694793d45f2fc529" + "Rev": "f848a144bdfc3d6dc7669d4b026ecc7a42ed4575" }, { "ImportPath": "github.com/itsjamie/gin-cors", @@ -44,14 +58,14 @@ "ImportPath": "github.com/kardianos/osext", "Rev": "6e7f843663477789fac7c02def0d0909e969b4e5" }, - { - "ImportPath": "github.com/kardianos/service", - "Rev": "1ab12303aaf4cf68a53a5717a31b5acd72c57019" - }, { "ImportPath": "github.com/kr/binarydist", "Rev": "9955b0ab8708602d411341e55fffd7e0700f86bd" }, + { + "ImportPath": "github.com/kr/fs", + "Rev": "2788f0dbd16903de03cb8186e5c7d97b69ad387b" + }, { "ImportPath": "github.com/manucorporat/sse", "Rev": "c142f0f1baea5cef7f98a8a6c222f6134368c1f5" @@ -60,51 +74,84 @@ "ImportPath": "github.com/mattn/go-colorable", "Rev": "40e4aedc8fabf8c23e040057540867186712faa5" }, + { + "ImportPath": "github.com/mattn/go-isatty", + "Rev": "ae0b1f8f8004be68d791a576e3d8e7648ab41449" + }, + { + "ImportPath": "github.com/mattn/go-ole", + "Comment": "v0.1.0-13-g3de65c4", + "Rev": "3de65c40eb2a56df91d6cf1a2486f1eb9d3c04eb" + }, + { + "ImportPath": "github.com/mattn/go-shellwords", + "Rev": "f4e566c536cf69158e808ec28ef4182a37fdc981" + }, { "ImportPath": "github.com/miekg/dns", - "Rev": "7864d445e5087e8d761dbefec43f29b92f7650eb" + "Rev": "3e549e2f6fd420cdffa528144b925305401bf55c" }, { "ImportPath": "github.com/oleksandr/bonjour", "Rev": "415cafc6ab8894ea7b7bcbed933ce2d8c611683c" }, + { + "ImportPath": "github.com/pivotal-golang/archiver/extractor", + "Rev": "f598990ddfeda2767a09346acf844a7d216c1256" + }, + { + "ImportPath": "github.com/pkg/sftp", + "Rev": "9d712e91b1f05c35bf7e8fa71a1b09392925d452" + }, { "ImportPath": "github.com/sanderhahn/gozip/patchzip", "Rev": "85893825032e0136f506cc9e3f36d42d56305ee9" }, + { + "ImportPath": "github.com/sfreiberg/simplessh", + "Rev": "e2df5a8be6f36be66ed1af2e8767a354788e902b" + }, { "ImportPath": "github.com/skratchdot/open-golang/open", "Rev": "c8748311a7528d0ba7330d302adbc5a677ef9c9e" }, { - "ImportPath": "github.com/termie/go-shutil", - "Rev": "bcacb06fecaeec8dc42af03c87c6949f4a05c74c" + "ImportPath": "github.com/vharitonsky/iniflags", + "Comment": "v.1.0-22-g5f0bb03", + "Rev": "5f0bb0369da23c35ce1201e53783d957df85c23b" }, { - "ImportPath": "github.com/vharitonsky/iniflags", - "Comment": "v.1.0-21-g14f4b95", - "Rev": "14f4b95d09b99e2475e82c37a2f943ef2469a890" + "ImportPath": "github.com/xrash/smetrics", + "Rev": "81a89232431423f9140fa413823ce3045f02f19c" + }, + { + "ImportPath": "golang.org/x/crypto/curve25519", + "Rev": "c8b9e6388ef638d5a8a9d865c634befdc46a6784" + }, + { + "ImportPath": "golang.org/x/crypto/ssh", + "Rev": "c8b9e6388ef638d5a8a9d865c634befdc46a6784" }, { "ImportPath": "golang.org/x/net/context", - "Rev": "d9558e5c97f85372afee28cf2b6059d7d3818919" + "Rev": "84ba27dd5b2d8135e9da1395277f2c9333a2ffda" }, { "ImportPath": "golang.org/x/net/internal/iana", - "Rev": "d9558e5c97f85372afee28cf2b6059d7d3818919" + "Rev": "84ba27dd5b2d8135e9da1395277f2c9333a2ffda" }, { "ImportPath": "golang.org/x/net/ipv4", - "Rev": "d9558e5c97f85372afee28cf2b6059d7d3818919" + "Rev": "84ba27dd5b2d8135e9da1395277f2c9333a2ffda" }, { "ImportPath": "golang.org/x/net/ipv6", - "Rev": "d9558e5c97f85372afee28cf2b6059d7d3818919" + "Rev": "84ba27dd5b2d8135e9da1395277f2c9333a2ffda" }, { "ImportPath": "gopkg.in/bluesuncorp/validator.v5", - "Comment": "v5.10", - "Rev": "d2748d5ae5e5af5ec3a85e3a59bf0db9d741c82d" + "Comment": "v5.10.2", + "Rev": "ac33a23e6e6451492f246d6ed9384af421b71d0d" } ] } From 6e1d11033cb3010ee0c73e6bbcf091035f83b738 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Tue, 15 Dec 2015 10:39:12 +0100 Subject: [PATCH 18/31] add CA fields to self signed certificate --- certificates.go | 12 ++++++++++-- main.go | 23 +++++++++++++++-------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/certificates.go b/certificates.go index a1451b959..aacf4cf78 100644 --- a/certificates.go +++ b/certificates.go @@ -106,13 +106,16 @@ func generateCertificates() { template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ - Organization: []string{"Arduino LLC US"}, + Organization: []string{"Arduino LLC US"}, + Country: []string{"US"}, + CommonName: "localhost", + OrganizationalUnit: []string{"IT"}, }, NotBefore: notBefore, NotAfter: notAfter, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, } @@ -135,6 +138,11 @@ func generateCertificates() { log.Fatalf("Failed to create certificate: %s", err) } + // remove old certificates + os.Remove("cert.pem") + os.Remove("key.pem") + os.Remove("cert.cer") + certOut, err := os.Create("cert.pem") if err != nil { log.Fatalf("failed to open cert.pem for writing: %s", err) diff --git a/main.go b/main.go index 88789bf5a..236f0459b 100755 --- a/main.go +++ b/main.go @@ -5,6 +5,12 @@ package main import ( "flag" + log "github.com/Sirupsen/logrus" + "github.com/carlescere/scheduler" + "github.com/gin-gonic/gin" + "github.com/itsjamie/gin-cors" + "github.com/kardianos/osext" + "github.com/vharitonsky/iniflags" "os" "os/user" "path/filepath" @@ -12,13 +18,6 @@ import ( "strconv" "text/template" "time" - - log "github.com/Sirupsen/logrus" - "github.com/carlescere/scheduler" - "github.com/gin-gonic/gin" - "github.com/itsjamie/gin-cors" - "github.com/kardianos/osext" - "github.com/vharitonsky/iniflags" //"github.com/sanbornm/go-selfupdate/selfupdate" #included in update.go to change heavily ) @@ -75,6 +74,11 @@ func launchSelfLater() { log.Println("Done waiting 2 secs. Now launching...") } +func certHandler(c *gin.Context) { + c.Header("content-type", "application/x-x509-ca-cert") + c.File("cert.cer") +} + func main() { flag.Parse() @@ -232,6 +236,7 @@ func main() { })) r.GET("/", homeHandler) + r.GET("/certificate.crt", certHandler) r.POST("/upload", uploadHandler) r.GET("/socket.io/", socketHandler) r.POST("/socket.io/", socketHandler) @@ -393,7 +398,9 @@ body {
- Pause
+ Pause + +
From e3ac16a984e419fca86a152ddbb390e02e376679 Mon Sep 17 00:00:00 2001 From: Matteo Suppo Date: Thu, 17 Dec 2015 15:40:39 +0100 Subject: [PATCH 19/31] Create a certification authority --- certificates.go | 80 ++++++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/certificates.go b/certificates.go index aacf4cf78..30e454238 100644 --- a/certificates.go +++ b/certificates.go @@ -16,13 +16,13 @@ import ( "crypto/x509/pkix" "encoding/pem" "fmt" - log "github.com/Sirupsen/logrus" - "io/ioutil" "math/big" "net" "os" "strings" "time" + + log "github.com/Sirupsen/logrus" ) var ( @@ -61,37 +61,32 @@ func pemBlockForKey(priv interface{}) *pem.Block { } } -func generateCertificates() { - - var priv interface{} - var err error +func generateKey(ecdsaCurve string) (interface{}, error) { switch ecdsaCurve { case "": - priv, err = rsa.GenerateKey(rand.Reader, rsaBits) + return rsa.GenerateKey(rand.Reader, rsaBits) case "P224": - priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader) + return ecdsa.GenerateKey(elliptic.P224(), rand.Reader) case "P256": - priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + return ecdsa.GenerateKey(elliptic.P256(), rand.Reader) case "P384": - priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader) + return ecdsa.GenerateKey(elliptic.P384(), rand.Reader) case "P521": - priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader) + return ecdsa.GenerateKey(elliptic.P521(), rand.Reader) default: - fmt.Fprintf(os.Stderr, "Unrecognized elliptic curve: %q", ecdsaCurve) - os.Exit(1) - } - if err != nil { - log.Fatalf("failed to generate private key: %s", err) + return nil, fmt.Errorf("Unrecognized elliptic curve: %q", ecdsaCurve) } +} +func generateSingleCertificate(isCa bool) (*x509.Certificate, error) { var notBefore time.Time + var err error if len(validFrom) == 0 { notBefore = time.Now() } else { notBefore, err = time.Parse("Jan 2 15:04:05 2006", validFrom) if err != nil { - fmt.Fprintf(os.Stderr, "Failed to parse creation date: %s\n", err) - os.Exit(1) + return nil, fmt.Errorf("Failed to parse creation date: %s\n", err.Error()) } } @@ -100,7 +95,7 @@ func generateCertificates() { serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { - log.Fatalf("failed to generate serial number: %s", err) + return nil, fmt.Errorf("failed to generate serial number: %s\n", err.Error()) } template := x509.Certificate{ @@ -133,32 +128,43 @@ func generateCertificates() { template.KeyUsage |= x509.KeyUsageCertSign } - derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv) + return &template, nil +} + +func generateCertificates() { + + // Create the key for the certification authority + caKey, err := generateKey("") + if err != nil { + log.Error(err.Error()) + os.Exit(1) + } + + keyOut, err := os.OpenFile("ca.key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { - log.Fatalf("Failed to create certificate: %s", err) + log.Error(err.Error()) + os.Exit(1) } + pem.Encode(keyOut, pemBlockForKey(caKey)) + keyOut.Close() + log.Println("written ca.key.pem") - // remove old certificates - os.Remove("cert.pem") - os.Remove("key.pem") - os.Remove("cert.cer") + // Create the certification authority + caTemplate, err := generateSingleCertificate(true) - certOut, err := os.Create("cert.pem") if err != nil { - log.Fatalf("failed to open cert.pem for writing: %s", err) + log.Error(err.Error()) + os.Exit(1) } - pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) - certOut.Close() - log.Print("written cert.pem\n") - ioutil.WriteFile("cert.cer", derBytes, 0644) + derBytes, err := x509.CreateCertificate(rand.Reader, caTemplate, caTemplate, publicKey(caKey), caKey) - keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + certOut, err := os.Create("ca.crt.pem") if err != nil { - log.Print("failed to open key.pem for writing:", err) - return + log.Error(err.Error()) + os.Exit(1) } - pem.Encode(keyOut, pemBlockForKey(priv)) - keyOut.Close() - log.Print("written key.pem\n") + pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) + certOut.Close() + log.Print("written ca.crt.pem") } From 5cb9f10947700e4ba726d14076bed1d7c93e08e8 Mon Sep 17 00:00:00 2001 From: Matteo Suppo Date: Thu, 17 Dec 2015 16:35:31 +0100 Subject: [PATCH 20/31] Create a signed certificate --- certificates.go | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/certificates.go b/certificates.go index 30e454238..cbf138a0e 100644 --- a/certificates.go +++ b/certificates.go @@ -133,6 +133,11 @@ func generateSingleCertificate(isCa bool) (*x509.Certificate, error) { func generateCertificates() { + os.Remove("ca.cert.pem") + os.Remove("ca.key.pem") + os.Remove("cert.pem") + os.Remove("key.pem") + // Create the key for the certification authority caKey, err := generateKey("") if err != nil { @@ -159,12 +164,47 @@ func generateCertificates() { derBytes, err := x509.CreateCertificate(rand.Reader, caTemplate, caTemplate, publicKey(caKey), caKey) - certOut, err := os.Create("ca.crt.pem") + certOut, err := os.Create("ca.cert.pem") + if err != nil { + log.Error(err.Error()) + os.Exit(1) + } + pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) + certOut.Close() + log.Print("written ca.cert.pem") + + // Create the key for the final certificate + key, err := generateKey("") + if err != nil { + log.Error(err.Error()) + os.Exit(1) + } + + keyOut, err = os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + if err != nil { + log.Error(err.Error()) + os.Exit(1) + } + pem.Encode(keyOut, pemBlockForKey(key)) + keyOut.Close() + log.Println("written key.pem") + + // Create the final certificate + template, err := generateSingleCertificate(false) + + if err != nil { + log.Error(err.Error()) + os.Exit(1) + } + + derBytes, err = x509.CreateCertificate(rand.Reader, template, caTemplate, publicKey(key), key) + + certOut, err = os.Create("cert.pem") if err != nil { log.Error(err.Error()) os.Exit(1) } pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) certOut.Close() - log.Print("written ca.crt.pem") + log.Print("written cert.pem") } From c140d7a7f851de051a6c83101d7951ee036ab028 Mon Sep 17 00:00:00 2001 From: Matteo Suppo Date: Fri, 18 Dec 2015 16:08:58 +0100 Subject: [PATCH 21/31] Ensure the second certificate is not a CA --- certificates.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/certificates.go b/certificates.go index cbf138a0e..360b95f19 100644 --- a/certificates.go +++ b/certificates.go @@ -26,12 +26,10 @@ import ( ) var ( - host = "localhost" - validFrom = "" - validFor = 365 * 24 * time.Hour * 2 // 2 years - isCA = true - rsaBits = 2048 - ecdsaCurve = "" + host = "localhost" + validFrom = "" + validFor = 365 * 24 * time.Hour * 2 // 2 years + rsaBits = 2048 ) func publicKey(priv interface{}) interface{} { @@ -123,7 +121,7 @@ func generateSingleCertificate(isCa bool) (*x509.Certificate, error) { } } - if isCA { + if isCa { template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign } @@ -197,7 +195,7 @@ func generateCertificates() { os.Exit(1) } - derBytes, err = x509.CreateCertificate(rand.Reader, template, caTemplate, publicKey(key), key) + derBytes, err = x509.CreateCertificate(rand.Reader, template, caTemplate, publicKey(key), caKey) certOut, err = os.Create("cert.pem") if err != nil { From 8636c6d857d62a0b13e18518ee1225e3c0cad90b Mon Sep 17 00:00:00 2001 From: Matteo Suppo Date: Mon, 21 Dec 2015 16:39:46 +0100 Subject: [PATCH 22/31] Output certificate in cer form --- certificates.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/certificates.go b/certificates.go index 360b95f19..233f25d30 100644 --- a/certificates.go +++ b/certificates.go @@ -16,6 +16,7 @@ import ( "crypto/x509/pkix" "encoding/pem" "fmt" + "io/ioutil" "math/big" "net" "os" @@ -171,6 +172,9 @@ func generateCertificates() { certOut.Close() log.Print("written ca.cert.pem") + ioutil.WriteFile("ca.cert.cer", derBytes, 0644) + log.Print("written ca.cert.cer") + // Create the key for the final certificate key, err := generateKey("") if err != nil { From 647db9512178eabc0abdbc6883f5da8b80c25d9c Mon Sep 17 00:00:00 2001 From: Matteo Suppo Date: Mon, 21 Dec 2015 16:45:17 +0100 Subject: [PATCH 23/31] Hide certificate button --- main.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/main.go b/main.go index 236f0459b..e042ab288 100755 --- a/main.go +++ b/main.go @@ -5,12 +5,6 @@ package main import ( "flag" - log "github.com/Sirupsen/logrus" - "github.com/carlescere/scheduler" - "github.com/gin-gonic/gin" - "github.com/itsjamie/gin-cors" - "github.com/kardianos/osext" - "github.com/vharitonsky/iniflags" "os" "os/user" "path/filepath" @@ -18,6 +12,13 @@ import ( "strconv" "text/template" "time" + + log "github.com/Sirupsen/logrus" + "github.com/carlescere/scheduler" + "github.com/gin-gonic/gin" + "github.com/itsjamie/gin-cors" + "github.com/kardianos/osext" + "github.com/vharitonsky/iniflags" //"github.com/sanbornm/go-selfupdate/selfupdate" #included in update.go to change heavily ) @@ -399,7 +400,7 @@ body { Pause - + From 010b471b71bea7ea554b1213a997533c752c53a5 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Tue, 22 Dec 2015 17:32:05 +0100 Subject: [PATCH 24/31] fix old dependencies and unused code --- update.go | 54 +----------------------------------------------------- 1 file changed, 1 insertion(+), 53 deletions(-) diff --git a/update.go b/update.go index e2ffea7b6..f6d85b882 100644 --- a/update.go +++ b/update.go @@ -38,11 +38,10 @@ import ( "errors" "fmt" log "github.com/Sirupsen/logrus" - "github.com/inconshreveable/go-update" "github.com/kardianos/osext" "github.com/kr/binarydist" "github.com/pivotal-golang/archiver/extractor" - patch "github.com/sanderhahn/gozip/patchzip" + "gopkg.in/inconshreveable/go-update.v0" "io" "io/ioutil" "math/rand" @@ -69,57 +68,6 @@ func IsZip(path string) bool { return false } -func Zip(path string, dirs []string) (err error) { - if IsZip(path) { - return errors.New(path + " is already a zip file") - } - - f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644) - if err != nil { - return - } - defer f.Close() - - startoffset, err := f.Seek(0, os.SEEK_END) - if err != nil { - return - } - - w := patch.NewWriterAt(f, startoffset) - - for _, dir := range dirs { - err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - fh, err := patch.FileInfoHeader(info) - if err != nil { - return err - } - fh.Name = path - - p, err := w.CreateHeader(fh) - if err != nil { - return err - } - if !info.IsDir() { - content, err := ioutil.ReadFile(path) - if err != nil { - return err - } - _, err = p.Write(content) - if err != nil { - return err - } - } - return err - }) - } - err = w.Close() - return -} - func Unzip(zippath string, destination string) (err error) { r, err := zip.OpenReader(zippath) if err != nil { From aa13744156e8c05acba49227ebd07c6869ca8fe6 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Tue, 22 Dec 2015 18:04:33 +0100 Subject: [PATCH 25/31] update godeps --- Godeps/Godeps.json | 78 ++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 41 deletions(-) diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 63c8cb347..5bf8e5242 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -1,21 +1,25 @@ { - "ImportPath": "github.com/arduino/arduino-create-agent", - "GoVersion": "go1.4.2", + "ImportPath": ".", + "GoVersion": "go1.4", "Deps": [ { "ImportPath": "github.com/Sirupsen/logrus", - "Comment": "v0.8.6-1-g8bca266", - "Rev": "8bca2664072173a3c71db4c28ca8d304079b1787" + "Comment": "v0.8.7-53-g446d1c1", + "Rev": "446d1c146faa8ed3f4218f056fcd165f6bcfda81" }, { "ImportPath": "github.com/carlescere/scheduler", - "Comment": "0.1-11-gd39e4af", - "Rev": "d39e4af87bb89586f86db467fa203d353b5d34ff" + "Comment": "0.1-13-g025e9f5", + "Rev": "025e9f58462112b9fb636708374467aef7161289" }, { "ImportPath": "github.com/facchinm/go-serial", "Rev": "3cfbd2fab741f7c9d238cb3bd17980110c81bd46" }, + { + "ImportPath": "github.com/facchinm/go-serial-native", + "Rev": "6c62fb894d873784830ec370e85ab1f29c2e0324" + }, { "ImportPath": "github.com/facchinm/systray", "Rev": "b32308b0b662e45cde7c5986bc29def5d48bafbb" @@ -30,29 +34,25 @@ }, { "ImportPath": "github.com/gin-gonic/gin", - "Comment": "v1.0rc1-136-gfd5d429", - "Rev": "fd5d4294a5d5223d55fc76d7840f4b0ad91647bb" + "Comment": "v1.0rc1-148-g52fcc5d", + "Rev": "52fcc5dbf6e94df33ad313858fb94b713e9d1b4a" }, { "ImportPath": "github.com/googollee/go-engine.io", - "Rev": "5525e3de461352f4c88d28287161ca2272c024ac" + "Rev": "a66cf68b24e56df0cacdc6041b93742f983a296a" }, { "ImportPath": "github.com/googollee/go-socket.io", - "Comment": "0.9.x-35-g647d8ca", - "Rev": "647d8cabbf6b58e48570e56cb59692cbc8fdb1d3" + "Comment": "0.9.x-51-g14bb3d0", + "Rev": "14bb3d0368089a74cb52164a7a697cf404bda9c6" }, { "ImportPath": "github.com/gorilla/websocket", "Rev": "2dbddebb8266b93c5e6b119efb54e89043186f3f" }, - { - "ImportPath": "github.com/inconshreveable/go-update", - "Rev": "f848a144bdfc3d6dc7669d4b026ecc7a42ed4575" - }, { "ImportPath": "github.com/itsjamie/gin-cors", - "Rev": "bd9551838cd52133960a2f44ab990be71744b663" + "Rev": "9526714e382db4023de25bfdad89cec9b7446092" }, { "ImportPath": "github.com/kardianos/osext", @@ -68,32 +68,28 @@ }, { "ImportPath": "github.com/manucorporat/sse", - "Rev": "c142f0f1baea5cef7f98a8a6c222f6134368c1f5" + "Rev": "fe6ea2c8e398672518ef204bf0fbd9af858d0e15" }, { "ImportPath": "github.com/mattn/go-colorable", - "Rev": "40e4aedc8fabf8c23e040057540867186712faa5" + "Rev": "3dac7b4f76f6e17fb39b768b89e3783d16e237fe" }, { "ImportPath": "github.com/mattn/go-isatty", - "Rev": "ae0b1f8f8004be68d791a576e3d8e7648ab41449" - }, - { - "ImportPath": "github.com/mattn/go-ole", - "Comment": "v0.1.0-13-g3de65c4", - "Rev": "3de65c40eb2a56df91d6cf1a2486f1eb9d3c04eb" + "Rev": "56b76bdf51f7708750eac80fa38b952bb9f32639" }, { "ImportPath": "github.com/mattn/go-shellwords", + "Comment": "v1.0.0", "Rev": "f4e566c536cf69158e808ec28ef4182a37fdc981" }, { "ImportPath": "github.com/miekg/dns", - "Rev": "3e549e2f6fd420cdffa528144b925305401bf55c" + "Rev": "75e6e86cc601825c5dbcd4e0c209eab180997cd7" }, { "ImportPath": "github.com/oleksandr/bonjour", - "Rev": "415cafc6ab8894ea7b7bcbed933ce2d8c611683c" + "Rev": "7ee314fe2bb898db0072d9af4b540b816fe7c6b5" }, { "ImportPath": "github.com/pivotal-golang/archiver/extractor", @@ -101,11 +97,7 @@ }, { "ImportPath": "github.com/pkg/sftp", - "Rev": "9d712e91b1f05c35bf7e8fa71a1b09392925d452" - }, - { - "ImportPath": "github.com/sanderhahn/gozip/patchzip", - "Rev": "85893825032e0136f506cc9e3f36d42d56305ee9" + "Rev": "2bc00847a6f77f5d32fa46b0ab829f0531d73244" }, { "ImportPath": "github.com/sfreiberg/simplessh", @@ -117,8 +109,8 @@ }, { "ImportPath": "github.com/vharitonsky/iniflags", - "Comment": "v.1.0-22-g5f0bb03", - "Rev": "5f0bb0369da23c35ce1201e53783d957df85c23b" + "Comment": "v.1.0-28-g02b57ef", + "Rev": "02b57ef987a5ee59eedc7dcd93315a43f6dcc4a7" }, { "ImportPath": "github.com/xrash/smetrics", @@ -126,20 +118,16 @@ }, { "ImportPath": "golang.org/x/crypto/curve25519", - "Rev": "c8b9e6388ef638d5a8a9d865c634befdc46a6784" + "Rev": "f18420efc3b4f8e9f3d51f6bd2476e92c46260e9" }, { "ImportPath": "golang.org/x/crypto/ssh", - "Rev": "c8b9e6388ef638d5a8a9d865c634befdc46a6784" + "Rev": "f18420efc3b4f8e9f3d51f6bd2476e92c46260e9" }, { "ImportPath": "golang.org/x/net/context", "Rev": "84ba27dd5b2d8135e9da1395277f2c9333a2ffda" }, - { - "ImportPath": "golang.org/x/net/internal/iana", - "Rev": "84ba27dd5b2d8135e9da1395277f2c9333a2ffda" - }, { "ImportPath": "golang.org/x/net/ipv4", "Rev": "84ba27dd5b2d8135e9da1395277f2c9333a2ffda" @@ -148,10 +136,18 @@ "ImportPath": "golang.org/x/net/ipv6", "Rev": "84ba27dd5b2d8135e9da1395277f2c9333a2ffda" }, + { + "ImportPath": "golang.org/x/sys/unix", + "Rev": "833a04a10549a95dc34458c195cbad61bbb6cb4d" + }, { "ImportPath": "gopkg.in/bluesuncorp/validator.v5", - "Comment": "v5.10.2", - "Rev": "ac33a23e6e6451492f246d6ed9384af421b71d0d" + "Comment": "v5.12", + "Rev": "d5acf1dac43705f8bfbb71d878e290e2bed3950b" + }, + { + "ImportPath": "gopkg.in/inconshreveable/go-update.v0", + "Rev": "d8b0b1d421aa1cbf392c05869f8abbc669bb7066" } ] } From 0f756a3a06354a841db59b91f3e3752d65cfcac2 Mon Sep 17 00:00:00 2001 From: Matteo Suppo Date: Fri, 8 Jan 2016 11:24:30 +0100 Subject: [PATCH 26/31] Use a different key --- certificates.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/certificates.go b/certificates.go index 233f25d30..3900c6d6c 100644 --- a/certificates.go +++ b/certificates.go @@ -138,7 +138,7 @@ func generateCertificates() { os.Remove("key.pem") // Create the key for the certification authority - caKey, err := generateKey("") + caKey, err := generateKey("P256") if err != nil { log.Error(err.Error()) os.Exit(1) @@ -176,7 +176,7 @@ func generateCertificates() { log.Print("written ca.cert.cer") // Create the key for the final certificate - key, err := generateKey("") + key, err := generateKey("P256") if err != nil { log.Error(err.Error()) os.Exit(1) From 37c1917b40a9d1b8c370d4b5adbd369094d26521 Mon Sep 17 00:00:00 2001 From: Matteo Suppo Date: Fri, 8 Jan 2016 12:17:06 +0100 Subject: [PATCH 27/31] We need to use two different CommonName --- certificates.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/certificates.go b/certificates.go index 3900c6d6c..23354972e 100644 --- a/certificates.go +++ b/certificates.go @@ -125,6 +125,7 @@ func generateSingleCertificate(isCa bool) (*x509.Certificate, error) { if isCa { template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign + template.Subject.CommonName = "Arduino" } return &template, nil @@ -209,4 +210,8 @@ func generateCertificates() { pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) certOut.Close() log.Print("written cert.pem") + + ioutil.WriteFile("cert.cer", derBytes, 0644) + log.Print("written cert.cer") + } From 2c881d8091c28152799464ed43004e6ba9066e31 Mon Sep 17 00:00:00 2001 From: Matteo Suppo Date: Mon, 11 Jan 2016 15:48:34 +0100 Subject: [PATCH 28/31] Add template for other browsers than firefox --- certificates.go | 19 +++++++++++++++++++ main.go | 7 ++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/certificates.go b/certificates.go index 23354972e..a6d0e09f2 100644 --- a/certificates.go +++ b/certificates.go @@ -21,9 +21,11 @@ import ( "net" "os" "strings" + "text/template" "time" log "github.com/Sirupsen/logrus" + "github.com/gin-gonic/gin" ) var ( @@ -215,3 +217,20 @@ func generateCertificates() { log.Print("written cert.cer") } + +func certHandler(c *gin.Context) { + if strings.Contains(c.Request.UserAgent(), "Firefox") { + c.Header("content-type", "application/x-x509-ca-cert") + c.File("ca.cert.cer") + return + } + noFirefoxTemplate.Execute(c.Writer, c.Request.Host) +} + +const noFirefoxTemplateHTML = ` + + + +` + +var noFirefoxTemplate = template.Must(template.New("home").Parse(noFirefoxTemplateHTML)) diff --git a/main.go b/main.go index e042ab288..e04ba5477 100755 --- a/main.go +++ b/main.go @@ -75,11 +75,6 @@ func launchSelfLater() { log.Println("Done waiting 2 secs. Now launching...") } -func certHandler(c *gin.Context) { - c.Header("content-type", "application/x-x509-ca-cert") - c.File("cert.cer") -} - func main() { flag.Parse() @@ -236,6 +231,8 @@ func main() { ValidateHeaders: false, })) + r.LoadHTMLFiles("templates/nofirefox.html") + r.GET("/", homeHandler) r.GET("/certificate.crt", certHandler) r.POST("/upload", uploadHandler) From c0647b9d96217dc4ee5f31910ea421b8a968d0f7 Mon Sep 17 00:00:00 2001 From: Matteo Suppo Date: Mon, 11 Jan 2016 17:24:45 +0100 Subject: [PATCH 29/31] Add page for wrong browser --- certificates.go | 100 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 2 deletions(-) diff --git a/certificates.go b/certificates.go index a6d0e09f2..15b5af94e 100644 --- a/certificates.go +++ b/certificates.go @@ -224,13 +224,109 @@ func certHandler(c *gin.Context) { c.File("ca.cert.cer") return } - noFirefoxTemplate.Execute(c.Writer, c.Request.Host) + noFirefoxTemplate.Execute(c.Writer, gin.H{ + "url": "http://" + c.Request.Host + c.Request.URL.String(), + }) } const noFirefoxTemplateHTML = ` + + + + + + +
+

Oops, this is not Firefox

+
+ +
+

You need to open this link in Firefox to trust this certificate: {{.host}}{{.url}}

+
+ + +` var noFirefoxTemplate = template.Must(template.New("home").Parse(noFirefoxTemplateHTML)) From 62d461f8595cebe6d684f600dc9d186baadd5db8 Mon Sep 17 00:00:00 2001 From: Matteo Suppo Date: Mon, 11 Jan 2016 17:26:49 +0100 Subject: [PATCH 30/31] Change padding --- certificates.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/certificates.go b/certificates.go index 15b5af94e..bfa4d11ac 100644 --- a/certificates.go +++ b/certificates.go @@ -260,7 +260,7 @@ body { height: auto; margin: 0 auto; min-width: 600px; - padding: 0 4%; + padding: 2% 4%; position: relative; width: 65%; box-shadow: 0 0 10px 0 rgba(21,110,114,.8); From 374fbbb68c054f925ef08f7be4401078c91253b7 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Tue, 12 Jan 2016 18:20:35 +0100 Subject: [PATCH 31/31] Make it clear that bash is required The script contains some bashims like echo -e so better make it explicit. Signed-off-by: Riccardo Magliocchetti --- compile_webidebridge.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compile_webidebridge.sh b/compile_webidebridge.sh index a66a3f8be..29f9231fc 100755 --- a/compile_webidebridge.sh +++ b/compile_webidebridge.sh @@ -1,3 +1,5 @@ +#!/bin/bash + # git submodule init # git submodule update