Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
376 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Copyright 2014 chaishushan@gmail.com. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package main | ||
|
||
import ( | ||
"os" | ||
) | ||
|
||
// GetPasswd returns the password read from the terminal without echoing input. | ||
// The returned byte array does not include end-of-line characters. | ||
func GetPasswd() []byte { | ||
return getPasswd(false) | ||
} | ||
|
||
// GetPasswdMasked returns the password read from the terminal, echoing asterisks. | ||
// The returned byte array does not include end-of-line characters. | ||
func GetPasswdMasked() []byte { | ||
return getPasswd(true) | ||
} | ||
|
||
// getPasswd returns the input read from terminal. | ||
// If masked is true, typing will be matched by asterisks on the screen. | ||
// Otherwise, typing will echo nothing. | ||
func getPasswd(masked bool) []byte { | ||
var pass, bs, mask []byte | ||
if masked { | ||
bs = []byte("\b \b") | ||
mask = []byte("*") | ||
} | ||
|
||
for { | ||
if v := getch(); v == 127 || v == 8 { | ||
if l := len(pass); l > 0 { | ||
pass = pass[:l-1] | ||
os.Stdout.Write(bs) | ||
} | ||
} else if v == 13 || v == 10 { | ||
break | ||
} else { | ||
pass = append(pass, v) | ||
os.Stdout.Write(mask) | ||
} | ||
} | ||
println() | ||
return pass | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
// Copyright 2014 chaishushan@gmail.com. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
// +build !windows | ||
|
||
package main | ||
|
||
import ( | ||
"runtime" | ||
"syscall" | ||
"unsafe" | ||
) | ||
|
||
// These constants are declared here, rather than importing | ||
// them from the syscall package as some syscall packages, even | ||
// on linux, for example gccgo, do not declare them. | ||
var ioctlReadTermios = func() uintptr { | ||
if runtime.GOOS == "linux" { | ||
return 0x5401 // syscall.TCGETS | ||
} else { | ||
return syscall.TIOCGETA | ||
} | ||
} | ||
var ioctlWriteTermios = func() uintptr { | ||
if runtime.GOOS == "linux" { | ||
return 0x5402 // syscall.TCSETS | ||
} else { | ||
return syscall.TIOCSETA | ||
} | ||
} | ||
|
||
// terminalState contains the state of a terminal. | ||
type terminalState struct { | ||
termios syscall.Termios | ||
} | ||
|
||
// terminalMakeRaw put the terminal connected to the given file descriptor into raw | ||
// mode and returns the previous state of the terminal so that it can be | ||
// restored. | ||
func terminalMakeRaw(fd int) (*terminalState, error) { | ||
var oldState terminalState | ||
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios(), uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 { | ||
return nil, err | ||
} | ||
|
||
newState := oldState.termios | ||
newState.Iflag &^= syscall.ISTRIP | syscall.INLCR | syscall.ICRNL | syscall.IGNCR | syscall.IXON | syscall.IXOFF | ||
newState.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.ISIG | ||
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios(), uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 { | ||
return nil, err | ||
} | ||
|
||
return &oldState, nil | ||
} | ||
|
||
// terminalRestore restores the terminal connected to the given file descriptor to a | ||
// previous state. | ||
func terminalRestore(fd int, state *terminalState) error { | ||
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios(), uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0) | ||
return err | ||
} | ||
|
||
func getch() byte { | ||
if oldState, err := terminalMakeRaw(0); err != nil { | ||
panic(err) | ||
} else { | ||
defer terminalRestore(0, oldState) | ||
} | ||
|
||
var buf [1]byte | ||
if n, err := syscall.Read(0, buf[:]); n == 0 || err != nil { | ||
panic(err) | ||
} | ||
return buf[0] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// Copyright 2014 chaishushan@gmail.com. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
// +build !windows | ||
|
||
package main | ||
|
||
import ( | ||
"syscall" | ||
"unsafe" | ||
) | ||
|
||
// These constants are declared here, rather than importing | ||
// them from the syscall package as some syscall packages, even | ||
// on linux, for example gccgo, do not declare them. | ||
var ioctlReadTermios = func() uintptr { | ||
return 0x5401 // syscall.TCGETS | ||
} | ||
var ioctlWriteTermios = func() uintptr { | ||
return 0x5402 // syscall.TCSETS | ||
} | ||
|
||
// terminalState contains the state of a terminal. | ||
type terminalState struct { | ||
termios syscall.Termios | ||
} | ||
|
||
// terminalMakeRaw put the terminal connected to the given file descriptor into raw | ||
// mode and returns the previous state of the terminal so that it can be | ||
// restored. | ||
func terminalMakeRaw(fd int) (*terminalState, error) { | ||
var oldState terminalState | ||
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios(), uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 { | ||
return nil, err | ||
} | ||
|
||
newState := oldState.termios | ||
newState.Iflag &^= syscall.ISTRIP | syscall.INLCR | syscall.ICRNL | syscall.IGNCR | syscall.IXON | syscall.IXOFF | ||
newState.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.ISIG | ||
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios(), uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 { | ||
return nil, err | ||
} | ||
|
||
return &oldState, nil | ||
} | ||
|
||
// terminalRestore restores the terminal connected to the given file descriptor to a | ||
// previous state. | ||
func terminalRestore(fd int, state *terminalState) error { | ||
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios(), uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0) | ||
return err | ||
} | ||
|
||
func getch() byte { | ||
if oldState, err := terminalMakeRaw(0); err != nil { | ||
panic(err) | ||
} else { | ||
defer terminalRestore(0, oldState) | ||
} | ||
|
||
var buf [1]byte | ||
if n, err := syscall.Read(0, buf[:]); n == 0 || err != nil { | ||
panic(err) | ||
} | ||
return buf[0] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// Copyright 2014 chaishushan@gmail.com. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package main | ||
|
||
import ( | ||
"syscall" | ||
"unicode/utf16" | ||
"unsafe" | ||
) | ||
|
||
var ( | ||
modkernel32 = syscall.NewLazyDLL("kernel32.dll") | ||
procReadConsole = modkernel32.NewProc("ReadConsoleW") | ||
procGetConsoleMode = modkernel32.NewProc("GetConsoleMode") | ||
procSetConsoleMode = modkernel32.NewProc("SetConsoleMode") | ||
) | ||
|
||
func getch() byte { | ||
var mode uint32 | ||
pMode := &mode | ||
procGetConsoleMode.Call(uintptr(syscall.Stdin), uintptr(unsafe.Pointer(pMode))) | ||
|
||
var echoMode, lineMode uint32 | ||
echoMode = 4 | ||
lineMode = 2 | ||
var newMode uint32 | ||
newMode = mode ^ (echoMode | lineMode) | ||
|
||
procSetConsoleMode.Call(uintptr(syscall.Stdin), uintptr(newMode)) | ||
|
||
line := make([]uint16, 1) | ||
pLine := &line[0] | ||
var n uint16 | ||
procReadConsole.Call( | ||
uintptr(syscall.Stdin), uintptr(unsafe.Pointer(pLine)), uintptr(len(line)), | ||
uintptr(unsafe.Pointer(&n)), | ||
) | ||
|
||
// For some reason n returned seems to big by 2 (Null terminated maybe?) | ||
if n > 2 { | ||
n -= 2 | ||
} | ||
|
||
b := []byte(string(utf16.Decode(line[:n]))) | ||
|
||
procSetConsoleMode.Call(uintptr(syscall.Stdin), uintptr(mode)) | ||
|
||
// Not sure how this could happen, but it did for someone | ||
if len(b) > 0 { | ||
return b[0] | ||
} else { | ||
return 13 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
// 以太坊工具箱(零第三方库依赖) 版权 @2019 柴树杉。 | ||
|
||
// 以太坊KeyStore文件查看器 | ||
// | ||
// 创建KeyStore文件步骤: | ||
// 1. 准备好私钥, 保存到key.txt文件 | ||
// 2. 执行 geth account import --keystore `pwd` key.txt | ||
// 3. 通过步骤2中输入的密码可以查看生成的文件 | ||
// 4. 私钥可以使用 <ethutil-vanity-gen> 工具生成 | ||
package main | ||
|
||
import ( | ||
"flag" | ||
"fmt" | ||
"io/ioutil" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/chai2010/ethutil" | ||
) | ||
|
||
var ( | ||
flagPassword = flag.String("password", "", "设置KeyStore文件的密码(默认手工输入)") | ||
flagGlobMatch = flag.Bool("glob-match", false, "采用Glob模式匹配文件名") | ||
flagShowKey = flag.Bool("show-key", false, "显示私钥") | ||
flagHelp = flag.Bool("h", false, "显示帮助") | ||
) | ||
|
||
func init() { | ||
flag.Usage = func() { | ||
fmt.Println("以太坊KeyStore文件查看器") | ||
fmt.Println() | ||
|
||
fmt.Println(" # 指定文件名") | ||
fmt.Println(" ethutil-cat-keystore file.json") | ||
fmt.Println(" ethutil-cat-keystore file.json file2.json") | ||
fmt.Println() | ||
|
||
fmt.Println(" # 显示私钥") | ||
fmt.Println(" ethutil-cat-keystore -show-key file.json") | ||
fmt.Println(" ethutil-cat-keystore -show-key file.json file2.json") | ||
fmt.Println() | ||
|
||
fmt.Println(" # Glob模式匹配") | ||
fmt.Println(" ethutil-cat-keystore -glob-match file?.json") | ||
fmt.Println(" ethutil-cat-keystore -glob-match file*.json") | ||
fmt.Println() | ||
|
||
fmt.Println("参数说明:") | ||
flag.PrintDefaults() | ||
fmt.Println() | ||
|
||
fmt.Println("https://github.com/chai2010/ethutil") | ||
fmt.Println("版权 @2019 柴树杉") | ||
} | ||
} | ||
|
||
func main() { | ||
flag.Parse() | ||
|
||
// 显示帮助信息 | ||
if *flagHelp || len(os.Args) < 2 { | ||
flag.Usage() | ||
os.Exit(0) | ||
} | ||
|
||
// 指定输入文件名 | ||
if flag.NArg() == 0 { | ||
fmt.Fprintf(os.Stderr, "错误: 缺少文件名!\n") | ||
os.Exit(-1) | ||
} | ||
|
||
// 读取文件名列表 | ||
var files = flag.Args() | ||
|
||
// Glob模式展开文件列表 | ||
if *flagGlobMatch { | ||
files = []string{} | ||
for _, pattern := range flag.Args() { | ||
matches, err := filepath.Glob(pattern) | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "错误: %v\n", err) | ||
os.Exit(-1) | ||
} | ||
files = append(files, matches...) | ||
} | ||
} | ||
|
||
// 手工输入密码 | ||
if *flagPassword == "" { | ||
fmt.Printf("输入密码: ") | ||
*flagPassword = string(GetPasswdMasked()) | ||
if len(*flagPassword) <= 0 { | ||
fmt.Fprintf(os.Stderr, "错误: 密码不能为空!\n") | ||
os.Exit(-1) | ||
} | ||
} | ||
|
||
// 处理全部的ks文件 | ||
for _, s := range files { | ||
// 读取ks文件 | ||
keyjson, err := ioutil.ReadFile(s) | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "错误: 读文件 %q 失败: %v\n", s, err) | ||
os.Exit(-1) | ||
} | ||
|
||
// 解码ks文件 | ||
uuid, privateKey, err := ethutil.KeyStoreDecryptKey( | ||
[]byte(keyjson), *flagPassword, | ||
) | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "错误: 解密 %q 失败: %v\n", s, err) | ||
os.Exit(-1) | ||
} | ||
|
||
if *flagShowKey { | ||
fmt.Printf("<uuid:%s> <address:%s> <key:%s> <file:%s>\n", uuid, | ||
ethutil.GenAddressFromPrivateKey(privateKey), privateKey, | ||
filepath.Clean(s), | ||
) | ||
} else { | ||
fmt.Printf("<uuid:%s> <address:%s> <file:%s>\n", uuid, | ||
ethutil.GenAddressFromPrivateKey(privateKey), | ||
filepath.Clean(s), | ||
) | ||
} | ||
} | ||
} |