diff options
author | Unknown <joe2010xtmf@163.com> | 2014-03-16 05:24:13 -0400 |
---|---|---|
committer | Unknown <joe2010xtmf@163.com> | 2014-03-16 05:24:13 -0400 |
commit | ab747f279088c9ed6114c4227c71173ebd1e6f00 (patch) | |
tree | 941c225f2aed7933e063e8fb25e98ed6f7b78d50 /models/publickey.go | |
parent | 8de9517862acd77c27da015654fc236a6722d188 (diff) | |
download | gitea-ab747f279088c9ed6114c4227c71173ebd1e6f00.tar.gz gitea-ab747f279088c9ed6114c4227c71173ebd1e6f00.zip |
Fix delete SSH key in file
Diffstat (limited to 'models/publickey.go')
-rw-r--r-- | models/publickey.go | 88 |
1 files changed, 81 insertions, 7 deletions
diff --git a/models/publickey.go b/models/publickey.go index 49d7f30828..2f32dc3f09 100644 --- a/models/publickey.go +++ b/models/publickey.go @@ -1,21 +1,30 @@ +// Copyright 2014 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + package models import ( + "bufio" "fmt" + "io" "os" "os/exec" "path/filepath" + "strings" + "sync" "time" "github.com/Unknwon/com" ) var ( + sshOpLocker = sync.Mutex{} //publicKeyRootPath string - sshPath string - appPath string - tmplPublicKey = "### autogenerated by gitgos, DO NOT EDIT\n" + - "command=\"%s serv key-%d\",no-port-forwarding," + + sshPath string + appPath string + // "### autogenerated by gitgos, DO NOT EDIT\n" + tmplPublicKey = "command=\"%s serv key-%d\",no-port-forwarding," + "no-X11-forwarding,no-agent-forwarding,no-pty %s\n" ) @@ -77,9 +86,69 @@ func AddPublicKey(key *PublicKey) error { return nil } -func DeletePublicKey(key *PublicKey) error { - _, err := orm.Delete(key) - return err +// DeletePublicKey deletes SSH key information both in database and authorized_keys file. +func DeletePublicKey(key *PublicKey) (err error) { + if _, err = orm.Delete(key); err != nil { + return err + } + + sshOpLocker.Lock() + defer sshOpLocker.Unlock() + + p := filepath.Join(sshPath, "authorized_keys") + tmpP := filepath.Join(sshPath, "authorized_keys.tmp") + fr, err := os.Open(p) + if err != nil { + return err + } + defer fr.Close() + + fw, err := os.Create(tmpP) + if err != nil { + return err + } + defer fw.Close() + + buf := bufio.NewReader(fr) + for { + line, errRead := buf.ReadString('\n') + line = strings.TrimSpace(line) + + if errRead != nil { + if errRead != io.EOF { + return errRead + } + + // Reached end of file, if nothing to read then break, + // otherwise handle the last line. + if len(line) == 0 { + break + } + } + + // Found the line and copy rest of file. + if strings.Contains(line, key.Content) { + if _, err = io.Copy(fw, fr); err != nil { + return err + } + break + } + + // Still finding the line, copy the line that currently read. + if _, err = fw.WriteString(line + "\n"); err != nil { + return err + } + + if errRead == io.EOF { + break + } + } + + if err = os.Remove(p); err != nil { + return err + } + + return os.Rename(tmpP, p) } func ListPublicKey(userId int64) ([]PublicKey, error) { @@ -89,11 +158,16 @@ func ListPublicKey(userId int64) ([]PublicKey, error) { } func SaveAuthorizedKeyFile(key *PublicKey) error { + sshOpLocker.Lock() + defer sshOpLocker.Unlock() + p := filepath.Join(sshPath, "authorized_keys") f, err := os.OpenFile(p, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600) if err != nil { return err } + defer f.Close() + //os.Chmod(p, 0600) _, err = f.WriteString(GenAuthorizedKey(key.Id, key.Content)) return err |