|
|
@ -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 |
|
|
|