func NewRepoContext() { zip.Verbose = false // Check Git installation. if _, err := exec.LookPath("git"); err != nil { log.Fatal(4, "Fail to test 'git' command: %v (forgotten install?)", err) } // Check Git version. ver, err := git.GetVersion() if err != nil { log.Fatal(4, "Fail to get Git version: %v", err) } reqVer, err := git.ParseVersion("1.7.1") if err != nil { log.Fatal(4, "Fail to parse required Git version: %v", err) } if ver.LessThan(reqVer) { log.Fatal(4, "Gogs requires Git version greater or equal to 1.7.1") } // Git requires setting user.name and user.email in order to commit changes. for configKey, defaultValue := range map[string]string{"user.name": "Gogs", "user.email": "*****@*****.**"} { if stdout, stderr, err := process.Exec("NewRepoContext(get setting)", "git", "config", "--get", configKey); err != nil || strings.TrimSpace(stdout) == "" { // ExitError indicates this config is not set if _, ok := err.(*exec.ExitError); ok || strings.TrimSpace(stdout) == "" { if _, stderr, gerr := process.Exec("NewRepoContext(set "+configKey+")", "git", "config", "--global", configKey, defaultValue); gerr != nil { log.Fatal(4, "Fail to set git %s(%s): %s", configKey, gerr, stderr) } log.Info("Git config %s set to %s", configKey, defaultValue) } else { log.Fatal(4, "Fail to get git %s(%s): %s", configKey, err, stderr) } } } // Set git some configurations. if _, stderr, err := process.Exec("NewRepoContext(git config --global core.quotepath false)", "git", "config", "--global", "core.quotepath", "false"); err != nil { log.Fatal(4, "Fail to execute 'git config --global core.quotepath false': %s", stderr) } }
// CheckPublicKeyString checks if the given public key string is recognized by SSH. func CheckPublicKeyString(content string) (_ string, err error) { content, err = parseKeyString(content) if err != nil { return "", err } content = strings.TrimRight(content, "\n\r") if strings.ContainsAny(content, "\n\r") { return "", errors.New("only a single line with a single key please") } // write the key to a file… tmpFile, err := ioutil.TempFile(os.TempDir(), "keytest") if err != nil { return "", err } tmpPath := tmpFile.Name() defer os.Remove(tmpPath) tmpFile.WriteString(content) tmpFile.Close() // Check if ssh-keygen recognizes its contents. stdout, stderr, err := process.Exec("CheckPublicKeyString", "ssh-keygen", "-l", "-f", tmpPath) if err != nil { return "", errors.New("ssh-keygen -l -f: " + stderr) } else if len(stdout) < 2 { return "", errors.New("ssh-keygen returned not enough output to evaluate the key: " + stdout) } // The ssh-keygen in Windows does not print key type, so no need go further. if setting.IsWindows { return content, nil } sshKeygenOutput := strings.Split(stdout, " ") if len(sshKeygenOutput) < 4 { return content, ErrKeyUnableVerify } // Check if key type and key size match. if !setting.Service.DisableMinimumKeySizeCheck { keySize := com.StrTo(sshKeygenOutput[0]).MustInt() if keySize == 0 { return "", errors.New("cannot get key size of the given key") } keyType := strings.TrimSpace(sshKeygenOutput[len(sshKeygenOutput)-1]) if minimumKeySize := minimumKeySizes[keyType]; minimumKeySize == 0 { return "", errors.New("sorry, unrecognized public key type") } else if keySize < minimumKeySize { return "", fmt.Errorf("the minimum accepted size of a public key %s is %d", keyType, minimumKeySize) } } return content, nil }
func addKey(e Engine, key *PublicKey) (err error) { // Calculate fingerprint. tmpPath := strings.Replace(path.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().Nanosecond()), "id_rsa.pub"), "\\", "/", -1) os.MkdirAll(path.Dir(tmpPath), os.ModePerm) if err = ioutil.WriteFile(tmpPath, []byte(key.Content), 0644); err != nil { return err } stdout, stderr, err := process.Exec("AddPublicKey", "ssh-keygen", "-l", "-f", tmpPath) if err != nil { return errors.New("ssh-keygen -l -f: " + stderr) } else if len(stdout) < 2 { return errors.New("not enough output for calculating fingerprint: " + stdout) } key.Fingerprint = strings.Split(stdout, " ")[1] // Save SSH key. if _, err = e.Insert(key); err != nil { return err } return saveAuthorizedKeyFile(key) }
func prepareRepoCommit(repo *Repository, tmpDir, repoPath string, opts CreateRepoOptions) error { // Clone to temprory path and do the init commit. _, stderr, err := process.Exec( fmt.Sprintf("initRepository(git clone): %s", repoPath), "git", "clone", repoPath, tmpDir) if err != nil { return fmt.Errorf("git clone: %v - %s", err, stderr) } // README data, err := getRepoInitFile("readme", opts.Readme) if err != nil { return fmt.Errorf("getRepoInitFile[%s]: %v", opts.Readme, err) } cloneLink, err := repo.CloneLink() if err != nil { return fmt.Errorf("CloneLink: %v", err) } match := map[string]string{ "Name": repo.Name, "Description": repo.Description, "CloneURL.SSH": cloneLink.SSH, "CloneURL.HTTPS": cloneLink.HTTPS, } if err = ioutil.WriteFile(filepath.Join(tmpDir, "README.md"), []byte(com.Expand(string(data), match)), 0644); err != nil { return fmt.Errorf("write README.md: %v", err) } // .gitignore if len(opts.Gitignores) > 0 { var buf bytes.Buffer names := strings.Split(opts.Gitignores, ",") for _, name := range names { data, err = getRepoInitFile("gitignore", name) if err != nil { return fmt.Errorf("getRepoInitFile[%s]: %v", name, err) } buf.WriteString("# ---> " + name + "\n") buf.Write(data) buf.WriteString("\n") } if buf.Len() > 0 { if err = ioutil.WriteFile(filepath.Join(tmpDir, ".gitignore"), buf.Bytes(), 0644); err != nil { return fmt.Errorf("write .gitignore: %v", err) } } } // LICENSE if len(opts.License) > 0 { data, err = getRepoInitFile("license", opts.License) if err != nil { return fmt.Errorf("getRepoInitFile[%s]: %v", opts.License, err) } if err = ioutil.WriteFile(filepath.Join(tmpDir, "LICENSE"), data, 0644); err != nil { return fmt.Errorf("write LICENSE: %v", err) } } return nil }