예제 #1
0
파일: msg.go 프로젝트: JonathanLogan/mute
func muteprotoDeliver(
	c *cli.Context,
	envelope string,
) (resend bool, err error) {
	args := []string{
		"--homedir", c.GlobalString("homedir"),
		"--loglevel", c.GlobalString("loglevel"),
		"--logdir", c.GlobalString("logdir"),
		"deliver",
	}
	cmd := exec.Command("muteproto", args...)
	stdin, err := cmd.StdinPipe()
	if err != nil {
		return false, err
	}
	var errbuf bytes.Buffer
	cmd.Stderr = &errbuf
	if err := cmd.Start(); err != nil {
		return false, err
	}
	if _, err := io.WriteString(stdin, envelope); err != nil {
		return false, err
	}
	stdin.Close()
	if err := cmd.Wait(); err != nil {
		return false,
			log.Errorf("%s: %s", err, strings.TrimSpace(errbuf.String()))
	}
	if len(errbuf.String()) > 0 {
		errstr := strings.TrimSpace(errbuf.String())
		if !strings.HasPrefix(errstr, "RESEND:\t") {
			return false,
				log.Errorf("ctrlengine: muteproto status output not parsable: %s", errstr)
		}
		log.Warn(errstr)
		resend = true
	}
	return
}
예제 #2
0
func (ce *CtrlEngine) getConfig(homedir string, offline bool) error {
	// read default config
	netDomain, _, _ := def.ConfigParams()
	jsn, err := ce.msgDB.GetValue(netDomain)
	if err != nil {
		return err
	}
	if jsn != "" {
		if err := json.Unmarshal([]byte(jsn), &ce.config); err != nil {
			return err
		}
		// apply old configuration
		err := def.InitMute(&ce.config)
		if err != nil {
			// init failed -> update config (which will try init again)
			fmt.Fprintf(ce.fileTable.StatusFP,
				"initialization failed, try to update config\n")
			if offline {
				return log.Error("ctrlengine: cannot fetch config in " +
					"--offline mode, run without")
			}
			err := ce.upkeepFetchconf(ce.msgDB, homedir, false, nil,
				ce.fileTable.StatusFP)
			if err != nil {
				return err
			}
		} else {
			// fetch new configuration, if last fetch is older than 24h
			timestr, err := ce.msgDB.GetValue("time." + netDomain)
			if err != nil {
				return err
			}
			if timestr != "" {
				t, err := strconv.ParseInt(timestr, 10, 64)
				if err != nil {
					return log.Error(err)
				}
				last := time.Now().Sub(time.Unix(t, 0))
				if last > def.FetchconfMinDuration {
					if offline {
						if last > def.FetchconfMaxDuration {
							return log.Error("ctrlengine: configuration is " +
								"outdated, please run without --offline")
						}
						log.Warn("ctrlengine: cannot fetch outdated config " +
							"in --offline mode")
						fmt.Fprintf(ce.fileTable.StatusFP,
							"ctrlengine: cannot fetch outdated config in "+
								"--offline mode\n")
					} else {
						// update config
						err := ce.upkeepFetchconf(ce.msgDB, homedir, false, nil,
							ce.fileTable.StatusFP)
						if err != nil {
							return err
						}
					}
				}
			}
		}
	} else {
		// no config found, fetch it
		if offline {
			return log.Error("ctrlengine: cannot fetch config in --offline mode")
		}
		fmt.Fprintf(ce.fileTable.StatusFP, "no system config found\n")
		err := ce.upkeepFetchconf(ce.msgDB, homedir, false, nil,
			ce.fileTable.StatusFP)
		if err != nil {
			return err
		}
	}
	return nil
}
예제 #3
0
파일: msg.go 프로젝트: JonathanLogan/mute
func mutecryptDecrypt(
	c *cli.Context,
	passphrase, enc []byte,
	statusFP io.Writer,
) (senderID, message string, err error) {
	args := []string{
		"--homedir", c.GlobalString("homedir"),
		"--loglevel", c.GlobalString("loglevel"),
		"--logdir", c.GlobalString("logdir"),
		"decrypt",
	}
	cmd := exec.Command("mutecrypt", args...)
	stdin, err := cmd.StdinPipe()
	if err != nil {
		return "", "", err
	}
	var outbuf bytes.Buffer
	cmd.Stdout = &outbuf
	var errbuf bytes.Buffer
	cmd.Stderr = &errbuf
	ppR, ppW, err := os.Pipe()
	if err != nil {
		return "", "", log.Error(err)
	}
	defer ppR.Close()
	ppW.Write(passphrase)
	ppW.Close()
	cmd.ExtraFiles = append(cmd.ExtraFiles, ppR)
	if err := cmd.Start(); err != nil {
		return "", "", log.Error(err)
	}
	if _, err := stdin.Write(enc); err != nil {
		return "", "", log.Error(err)
	}
	stdin.Close()
	if err := cmd.Wait(); err != nil {
		errstr := strings.TrimSpace(errbuf.String())
		if strings.HasSuffix(errstr, msg.ErrNoPreHeaderKey.Error()) {
			log.Warn("could not decrypt pre-header, message dropped")
			fmt.Fprintf(statusFP,
				"could not decrypt pre-header, message dropped\n")
			return "", "", nil
		}
		return "", "", log.Errorf("%s: %s", err, errstr)
	}
	// TODO: parse and process signature!
	scanner := bufio.NewScanner(&errbuf)
	if scanner.Scan() {
		line := scanner.Text()
		parts := strings.Split(line, "\t")
		if len(parts) != 2 || parts[0] != "SENDERIDENTITY:" {
			return "", "",
				log.Errorf("ctrlengine: mutecrypt status output not parsable: %s", line)
		}
		senderID = parts[1]
	} else {
		return "", "", log.Error("ctrlengine: expecting mutecrypt output")
	}
	if err := scanner.Err(); err != nil {
		return "", "", log.Error(err)
	}

	message = outbuf.String()
	return
}