Skip to content

Instantly share code, notes, and snippets.

@syossan27
Created December 22, 2018 05:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save syossan27/2b330c6e29ff3408a5b1a7a7cc7f7c0a to your computer and use it in GitHub Desktop.
Save syossan27/2b330c6e29ff3408a5b1a7a7cc7f7c0a to your computer and use it in GitHub Desktop.
func (cs *Connections) Add(name string) {
// 同名の接続情報があった場合にエラー
if cs.Exist(name) {
foundation.PrintError("Connection name already exists")
}
// Prompterを用いてユーザーの入力値を取得
host, user, password := foundation.AddPrompt()
// 接続情報管理ファイルに書き込み
conn := New(name, host, user, password)
*cs = append(*cs, *conn)
save(cs)
}
func AddPrompt() (string, string, string) {
var host = prompter.Prompt("Host", "")
if host == "" {
PrintError("Invalid Host")
}
var user = prompter.Prompt("User", "")
if user == "" {
PrintError("Invalid User")
}
var password = prompter.Password("Password")
if password == "" {
PrintError("Invalid Password")
}
return host, user, password
}
func New(name, host, user, password string) *Connection {
return &Connection{
Name: name,
Host: host,
User: user,
Password: password,
}
}
func save(cs *Connections) {
// AES暗号の鍵として.ssh/id_rsaの内容を取得する
key := foundation.GetKey(foundation.KeyPath)
// 接続情報管理ファイルを開く
f, err := os.Create(foundation.StorePath)
if err != nil {
foundation.PrintError("Failed to open store file")
}
defer f.Close()
// 接続情報をYAMLに変換
p, err := yaml.Marshal(cs)
if err != nil {
foundation.PrintError("Failed to marshal connections yaml")
}
// 暗号化
enc, err := foundation.Encrypt(key, p)
if err != nil {
foundation.PrintError("Failed to encrypt connections")
}
// 接続情報管理ファイルに書き込み
_, err = f.WriteString(enc)
if err != nil {
foundation.PrintError("Failed to write string to store file")
}
}
// 接続情報と鍵を基に暗号化し、base64でエンコード
func Encrypt(key []byte, data []byte) (string, error) {
// ブロック・サイファーでのブロックの生成
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
// ブロックサイズに暗号化するデータサイズを足したバイト数の配列を用意
cipherText := make([]byte, aes.BlockSize+len(data))
// 初期化ベクトル(IV)の生成
iv := cipherText[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return "", err
}
stream := cipher.NewCTR(block, iv) // CTRモードで鍵ストリームを生成
stream.XORKeyStream(cipherText[aes.BlockSize:], data) // 平文データに対して排他的論理和をかける
encoded := base64.StdEncoding.EncodeToString(cipherText) // base64エンコード
return encoded, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment