read-password 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ext/extconf.rb +21 -0
- data/ext/noecho.c +119 -0
- data/lib/read-password.rb +83 -0
- metadata +78 -0
data/ext/extconf.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
if RUBY_PLATFORM =~ /(?<!dar)win|w32|java/
|
2
|
+
require 'mkmf'
|
3
|
+
require 'fakext'
|
4
|
+
|
5
|
+
Gem.fakext('noecho')
|
6
|
+
else
|
7
|
+
require 'mkmf'
|
8
|
+
|
9
|
+
ok = true
|
10
|
+
|
11
|
+
case
|
12
|
+
when %w[termios.h termio.h].find {|h| have_header(h) } then nil
|
13
|
+
when have_header('sgtty.h') then %w[stty gtty].each {|f| have_func(f, 'sgtty.h') }
|
14
|
+
else ok = false
|
15
|
+
end
|
16
|
+
|
17
|
+
have_header('sys/ioctl.h')
|
18
|
+
have_func("rb_io_get_write_io", "ruby/io.h")
|
19
|
+
|
20
|
+
create_makefile('io/noecho') if ok
|
21
|
+
end
|
data/ext/noecho.c
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#ifdef HAVE_RUBY_IO_H
|
3
|
+
# include "ruby/io.h"
|
4
|
+
#else
|
5
|
+
# include "rubyio.h"
|
6
|
+
#endif
|
7
|
+
|
8
|
+
#if defined HAVE_TERMIOS_H
|
9
|
+
# include <termios.h>
|
10
|
+
typedef struct termios conmode;
|
11
|
+
# define setattr(fd, t) (tcsetattr(fd, TCSAFLUSH, t) == 0)
|
12
|
+
# define getattr(fd, t) (tcgetattr(fd, t) == 0)
|
13
|
+
#elif defined HAVE_TERMIO_H
|
14
|
+
# include <termio.h>
|
15
|
+
typedef struct termio conmode;
|
16
|
+
# define setattr(fd, t) (ioctl(fd, TCSETAF, t) == 0)
|
17
|
+
# define getattr(fd, t) (ioctl(fd, TCGETA, t) == 0)
|
18
|
+
#elif defined HAVE_SGTTY_H
|
19
|
+
# include <sgtty.h>
|
20
|
+
typedef struct sgttyb conmode;
|
21
|
+
# ifdef HAVE_STTY
|
22
|
+
# define setattr(fd, t) (stty(fd, t) == 0)
|
23
|
+
# else
|
24
|
+
# define setattr(fd, t) (ioctl((fd), TIOCSETP, (t)) == 0)
|
25
|
+
# endif
|
26
|
+
# ifdef HAVE_GTTY
|
27
|
+
# define getattr(fd, t) (gtty(fd, t) == 0)
|
28
|
+
# else
|
29
|
+
# define getattr(fd, t) (ioctl((fd), TIOCGETP, (t)) == 0)
|
30
|
+
# endif
|
31
|
+
#endif
|
32
|
+
|
33
|
+
static void
|
34
|
+
set_noecho(conmode *t) {
|
35
|
+
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
|
36
|
+
t->c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
|
37
|
+
#elif defined HAVE_SGTTY_H
|
38
|
+
t->sg_flags &= ~ECHO;
|
39
|
+
#endif
|
40
|
+
}
|
41
|
+
|
42
|
+
static void
|
43
|
+
set_echo(conmode *t) {
|
44
|
+
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
|
45
|
+
t->c_lflag |= (ECHO | ECHOE | ECHOK | ECHONL);
|
46
|
+
#elif defined HAVE_SGTTY_H
|
47
|
+
t->sg_flags |= ECHO;
|
48
|
+
#endif
|
49
|
+
}
|
50
|
+
|
51
|
+
static int
|
52
|
+
echo_p(conmode *t) {
|
53
|
+
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
|
54
|
+
return (t->c_lflag & (ECHO | ECHOE | ECHOK | ECHONL)) != 0;
|
55
|
+
#elif defined HAVE_SGTTY_H
|
56
|
+
return (t->sg_flags & ECHO) != 0;
|
57
|
+
#endif
|
58
|
+
}
|
59
|
+
|
60
|
+
static int
|
61
|
+
get_fd(VALUE io) {
|
62
|
+
return FIX2INT(rb_funcall(io, rb_intern("fileno"), 0));
|
63
|
+
}
|
64
|
+
|
65
|
+
static VALUE
|
66
|
+
console_noecho(VALUE io) {
|
67
|
+
int fd = get_fd(io);
|
68
|
+
conmode t;
|
69
|
+
|
70
|
+
if (!getattr(fd, &t))
|
71
|
+
rb_raise(rb_eIOError, "Can't get attributes");
|
72
|
+
|
73
|
+
set_noecho(&t);
|
74
|
+
setattr(fd, &t);
|
75
|
+
return io;
|
76
|
+
}
|
77
|
+
|
78
|
+
static VALUE
|
79
|
+
console_echo(VALUE io) {
|
80
|
+
int fd = get_fd(io);
|
81
|
+
conmode t;
|
82
|
+
|
83
|
+
if (!getattr(fd, &t))
|
84
|
+
rb_raise(rb_eIOError, "Can't get attributes");
|
85
|
+
|
86
|
+
set_echo(&t);
|
87
|
+
setattr(fd, &t);
|
88
|
+
return io;
|
89
|
+
}
|
90
|
+
|
91
|
+
static VALUE
|
92
|
+
console_echo_p(VALUE io) {
|
93
|
+
int fd = get_fd(io);
|
94
|
+
conmode t;
|
95
|
+
|
96
|
+
if (!getattr(fd, &t))
|
97
|
+
rb_raise(rb_eIOError, "Can't get attributes");
|
98
|
+
|
99
|
+
return echo_p(&t) ? Qtrue : Qfalse;
|
100
|
+
}
|
101
|
+
|
102
|
+
static VALUE
|
103
|
+
console_set_echo(VALUE io, VALUE f) {
|
104
|
+
if (RTEST(f))
|
105
|
+
console_echo(io);
|
106
|
+
else
|
107
|
+
console_noecho(io);
|
108
|
+
|
109
|
+
return io;
|
110
|
+
}
|
111
|
+
|
112
|
+
|
113
|
+
void
|
114
|
+
Init_noecho(void) {
|
115
|
+
rb_define_method(rb_cIO, "echo=", console_set_echo, 1);
|
116
|
+
rb_define_method(rb_cIO, "echo?", console_echo_p, 0);
|
117
|
+
rb_define_method(rb_cIO, "echo", console_echo, 0);
|
118
|
+
rb_define_method(rb_cIO, "noecho", console_noecho, 0);
|
119
|
+
}
|
@@ -0,0 +1,83 @@
|
|
1
|
+
if RUBY_PLATFORM =~ /(?<!dar)win|w32/
|
2
|
+
require 'Win32API'
|
3
|
+
|
4
|
+
module Kernel
|
5
|
+
module API
|
6
|
+
GetStdHandle = Win32API.new('kernel32', 'GetStdHandle', ['l'], 'p')
|
7
|
+
GetConsoleMode = Win32API.new('kernel32', 'GetConsoleMode', ['l', 'p'], 'l')
|
8
|
+
SetConsoleMode = Win32API.new('kernel32', 'SetConsoleMode', ['l', 'l'], 'l')
|
9
|
+
ReadConsole = Win32API.new('kernel32', 'ReadConsole', ['l', 'p', 'l', 'p', 'p'], 'l')
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def get_std_handle(handle)
|
13
|
+
GetStdHandle.call(handle)
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_console_mode(handle)
|
17
|
+
lp_mode = ' ' * 4
|
18
|
+
GetConsoleMode.call(handle, lp_mode)
|
19
|
+
lp_mode.unpack('L').first
|
20
|
+
end
|
21
|
+
|
22
|
+
def set_console_mode(handle, lp_mode)
|
23
|
+
SetConsoleMode.call(handle, lp_mode)
|
24
|
+
end
|
25
|
+
|
26
|
+
def read_console(handle, n)
|
27
|
+
buf = ' ' * n
|
28
|
+
nocr = ' ' * 4
|
29
|
+
reserved = ' ' * 4
|
30
|
+
ReadConsole.call(handle, buf, n, nocr, reserved)
|
31
|
+
buf
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
ENABLE_ECHO_INPUT = 0x0004
|
37
|
+
|
38
|
+
def self.password(prompt='Password: ')
|
39
|
+
handle = API.get_std_handle(0xFFFFFFF6)
|
40
|
+
mode = API.get_console_mode(handle) rescue 9999
|
41
|
+
|
42
|
+
res = if (mode & ENABLE_ECHO_INPUT) == ENABLE_ECHO_INPUT
|
43
|
+
API.set_console_mode(handle, mode & ~ENABLE_ECHO_INPUT)
|
44
|
+
STDIN.gets.chomp.tap {
|
45
|
+
API.set_console_mode(handle, mode)
|
46
|
+
}
|
47
|
+
else
|
48
|
+
STDIN.gets.chomp
|
49
|
+
end
|
50
|
+
STDOUT.puts
|
51
|
+
|
52
|
+
res
|
53
|
+
end
|
54
|
+
end
|
55
|
+
elsif RUBY_PLATFORM =~ /java/
|
56
|
+
module Kernel
|
57
|
+
def self.password(prompt='Password: ')
|
58
|
+
Java::java.lang.String.new(Java::java.lang.System.console.readPassword(prompt)).to_s
|
59
|
+
rescue
|
60
|
+
raise RuntimeError, "Cannot read password"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
else
|
64
|
+
require 'io/noecho'
|
65
|
+
|
66
|
+
module Kernel
|
67
|
+
def self.password(prompt='Password: ')
|
68
|
+
STDOUT.print(prompt)
|
69
|
+
|
70
|
+
res = if STDIN.echo?
|
71
|
+
STDIN.noecho
|
72
|
+
STDIN.gets.chomp.tap {
|
73
|
+
STDIN.echo
|
74
|
+
}
|
75
|
+
else
|
76
|
+
STDIN.gets.chomp
|
77
|
+
end
|
78
|
+
|
79
|
+
STDOUT.puts
|
80
|
+
res
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: read-password
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- shura
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-10-04 00:00:00 +02:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: fakext
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :runtime
|
32
|
+
version_requirements: *id001
|
33
|
+
description: Read silently password on all ruby implementations and OS
|
34
|
+
email: shura1991@gmail.com
|
35
|
+
executables: []
|
36
|
+
|
37
|
+
extensions:
|
38
|
+
- ext/extconf.rb
|
39
|
+
extra_rdoc_files: []
|
40
|
+
|
41
|
+
files:
|
42
|
+
- lib/read-password.rb
|
43
|
+
- ext/noecho.c
|
44
|
+
- ext/extconf.rb
|
45
|
+
has_rdoc: true
|
46
|
+
homepage: http://github.com/shurizzle/ruby-read-password
|
47
|
+
licenses: []
|
48
|
+
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
version: "0"
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
segments:
|
68
|
+
- 0
|
69
|
+
version: "0"
|
70
|
+
requirements: []
|
71
|
+
|
72
|
+
rubyforge_project:
|
73
|
+
rubygems_version: 1.3.7
|
74
|
+
signing_key:
|
75
|
+
specification_version: 3
|
76
|
+
summary: Read silently password on all ruby implementations and OS
|
77
|
+
test_files: []
|
78
|
+
|