rpam2 3.1.0 → 4.0.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 8180810fbc2a5e9a9ac2eeac16e0a62bff594e6c
4
- data.tar.gz: d43a52c9d4e266a1a91bebceb057f29d955da4f3
2
+ SHA256:
3
+ metadata.gz: e5c4a544a01935abef0fcad198c54eac69eadf13f911ac9d232e12b0febe345a
4
+ data.tar.gz: 141df1f03c8fc332f68b8c7ef397a9040d2ba91c3ac4c4fd2639e41f3dc9f775
5
5
  SHA512:
6
- metadata.gz: f7172cb9bc9cb1a78c052d75f3663d430b222c5bd70c33bcb762e5a171899fb250eff5e0bb8a4404bb2647cb0dbfb0da24cc8d9d6739f7c8985e1511d3260588
7
- data.tar.gz: d14f701064970ddea61f52ab036fbfc86a7a030aa3a614d2b8a27c4e3c7e66d822b8a3985f11fe5dedd1a066f20c09dea81f71a5bb730f858d541d733551dcae
6
+ metadata.gz: 8d629dd561e80ad197493349953319477d7c7fd2d785dfdb2d30adf8b1c2ce4c6e6105b2ac73df18b3fb65dcdcb3087b3ba9464a5b1ae1a91e4aeba3cf402bda
7
+ data.tar.gz: 8bc5288e360b0e6778f10b719b5d11f12a05a649f08b7ac41225ff29431e60e57193b33c3aa7b0349d5e0ec6cd864d0265f270fc05a6c35e995c3f69d936810f
data/README.rdoc CHANGED
@@ -17,7 +17,7 @@
17
17
  else
18
18
  puts "Authentication failed"
19
19
  end
20
-
20
+
21
21
  puts Rpam2.listenv(nil, "user", "password") # uses default (rpam)
22
22
  puts Rpam2.listenv("servicename", "user", "password")
23
23
  puts Rpam2.listenv("servicename", "user", "password", true)
@@ -31,12 +31,19 @@
31
31
 
32
32
  == INSTALL:
33
33
 
34
- * gem install rpam2
34
+ gem install rpam2
35
+
36
+ or if it should not depend on pam:
37
+
38
+ ALLOW_NOPAM=true gem install rpam2
39
+
40
+ WARNING: Don't use rpam2 in this case except for test. It isn't safe
35
41
 
36
42
  Or manually:
37
43
 
38
44
  * gem build rpam2.gemspec
39
- * gem install ./rpam2-2.0.0.gem
45
+ * gem install ./rpam2-4.0.0.gem
46
+
40
47
 
41
48
  == Usage:
42
49
 
@@ -49,3 +56,10 @@ Rpam2.account("servicename", "username") => (true/false)
49
56
  Rpam2.getenv("servicename", "username", "password", "envvar", [opensession(true/false), ["RUSER", "RHOST"]]) => (string/nil)
50
57
 
51
58
  Rpam2.listenv("servicename", "username", "password", [opensession(true/false), ["RUSER", "RHOST"]]) => (hash/nil)
59
+
60
+
61
+ == Testing:
62
+ For test purposes can Rpam2 be filled with fake data. For this mode pam is not neccessary but then you may should not access not specified services.
63
+ Only services in fake_data are emulated the rest is redirected to real pam.
64
+
65
+ Rpam2.fake_data = { usernames: Set['alex', 'hugo', 'thomas'], servicenames: Set['service1', 'service2'], password: '123456', env: { email: 'me@example.com'} }
data/ext/rpam2/extconf.rb CHANGED
@@ -1,18 +1,27 @@
1
1
  require 'mkmf'
2
2
 
3
- abort "missing pam library" unless have_library("pam","pam_start")
4
- abort "missing pam library headers" unless have_header("security/pam_appl.h")
5
- abort "missing pam library headers" unless have_header("security/pam_modules.h")
6
-
7
- have_func("pam_end")
8
- have_func("pam_open_session")
9
- have_func("pam_close_session")
10
- have_func("pam_authenticate")
11
- have_func("pam_acct_mgmt")
12
- have_func("pam_chauthtok")
13
- have_func("pam_set_item")
14
- have_func("pam_get_item")
3
+ pam_installed = have_library("pam","pam_start") and have_header("security/pam_appl.h")
4
+ #pam_installed = false
5
+
6
+
7
+ abort "missing pam library or header" unless pam_installed || ENV['ALLOW_NOPAM']=='true'
8
+
9
+
15
10
  $CFLAGS << " -std=c99 "
16
11
 
12
+ if pam_installed
13
+ puts "Rpam2 build correctly (without stubs)" if ENV['ALLOW_NOPAM']=='true'
14
+ have_func("pam_end")
15
+ have_func("pam_open_session")
16
+ have_func("pam_close_session")
17
+ have_func("pam_authenticate")
18
+ have_func("pam_acct_mgmt")
19
+ have_func("pam_set_item")
20
+ have_func("pam_get_item")
21
+ else
22
+ warn "Rpam2 build didn't find pam headers/library, use pam stubs.\nONLY FOR TESTS OR IF PAM IS NOT USED. THIS MODE IS NOT SAFE IF PAM IS USED."
23
+ $CFLAGS << "-DWITHOUT_PAM_HEADER=1 "
24
+ end
25
+
17
26
 
18
27
  create_makefile("rpam2/rpam2")
data/ext/rpam2/rpam2.c CHANGED
@@ -1,6 +1,90 @@
1
1
  #include "ruby.h"
2
2
  #include <string.h>
3
+
4
+ #ifndef WITHOUT_PAM_HEADER
3
5
  #include <security/pam_appl.h>
6
+ #else
7
+ /* linux pam */
8
+ /* status */
9
+ #define PAM_SUCCESS 0
10
+ #define PAM_SYMBOL_ERR 2
11
+ #define PAM_BUF_ERR 5
12
+ #define PAM_CONV_ERR 19
13
+
14
+ /* items */
15
+ #define PAM_SERVICE 1
16
+ #define PAM_CONV 5
17
+ #define PAM_RHOST 4
18
+ #define PAM_RUSER 8
19
+
20
+ /* Messages */
21
+ #define PAM_PROMPT_ECHO_OFF 1
22
+ #define PAM_PROMPT_ECHO_ON 2
23
+ #define PAM_ERROR_MSG 3
24
+ #define PAM_TEXT_INFO 4
25
+
26
+ typedef struct pam_handle pam_handle_t;
27
+
28
+
29
+ struct pam_message {
30
+ int msg_style;
31
+ const char *msg;
32
+ };
33
+
34
+ struct pam_response {
35
+ char *resp;
36
+ int resp_retcode; /* currently un-used, zero expected */
37
+ };
38
+
39
+ /* The actual conversation structure itself */
40
+
41
+ struct pam_conv {
42
+ int (*conv)(int num_msg, const struct pam_message **msg,
43
+ struct pam_response **resp, void *appdata_ptr);
44
+ void *appdata_ptr;
45
+ };
46
+
47
+ // fix implicit function warnings:
48
+
49
+ int pam_start(const char *service_name, const char *user, const struct pam_conv *pam_conversation, pam_handle_t **pamh){
50
+ return PAM_SYMBOL_ERR;
51
+ };
52
+ int pam_end(pam_handle_t *pamh, int pam_status){
53
+ return PAM_SYMBOL_ERR;
54
+ }
55
+
56
+ int pam_authenticate(pam_handle_t *pamh, int flags){
57
+ return PAM_SYMBOL_ERR;
58
+ }
59
+ int pam_acct_mgmt(pam_handle_t *pamh, int flags){
60
+ return PAM_SYMBOL_ERR;
61
+ }
62
+ const char *pam_strerror(pam_handle_t *pamh, int errnum){
63
+ return "No PAM";
64
+ }
65
+ int pam_set_item(pam_handle_t *pamh, int item_type, const void *item){
66
+ return PAM_SYMBOL_ERR;
67
+ }
68
+ int pam_get_item(const pam_handle_t *pamh, int item_type, const void **item){
69
+ return PAM_SYMBOL_ERR;
70
+ }
71
+ char **pam_getenvlist(pam_handle_t *pamh){
72
+ return PAM_SYMBOL_ERR;
73
+ }
74
+ const char *pam_getenv(pam_handle_t *pamh, const char *name){
75
+ return PAM_SYMBOL_ERR;
76
+ }
77
+
78
+ int pam_open_session(pam_handle_t *pamh, int flags){
79
+ return PAM_SYMBOL_ERR;
80
+ }
81
+ int pam_close_session(pam_handle_t *pamh, int flags){
82
+ return PAM_SYMBOL_ERR;
83
+ }
84
+
85
+ #endif
86
+
87
+
4
88
 
5
89
  static const char *const
6
90
  rpam_default_servicename = "rpam";
@@ -90,7 +174,7 @@ static unsigned int _start(pam_handle_t* pamh, VALUE* service, char* password, V
90
174
  auth_c.conv = rpam_auth_conversation;
91
175
  authw.pw = password;
92
176
  auth_c.appdata_ptr = &authw;
93
-
177
+
94
178
  result = pam_set_item(pamh, PAM_CONV, &auth_c);
95
179
  if (result != PAM_SUCCESS) {
96
180
  rb_warn("SET CONV: %s", pam_strerror(pamh, result));
@@ -119,7 +203,7 @@ static VALUE method_authpam(VALUE self, VALUE servicename, VALUE username, VALUE
119
203
  rb_warn("INIT: %s", pam_strerror(pamh, result));
120
204
  return Qfalse;
121
205
  }
122
-
206
+
123
207
  result = _start(pamh, &servicename, StringValueCStr(password), &ruser, &rhost);
124
208
  if(result!=PAM_SUCCESS)
125
209
  return Qfalse;
@@ -138,7 +222,7 @@ static VALUE method_accountpam(VALUE self, VALUE servicename, VALUE username) {
138
222
  pam_handle_t* pamh = NULL;
139
223
  unsigned int result=0;
140
224
  struct pam_conv auth_c = {0,0};
141
-
225
+
142
226
  Check_Type(username, T_STRING);
143
227
 
144
228
  result = pam_start(rpam_default_servicename, StringValueCStr(username), &auth_c, &pamh);
@@ -162,7 +246,7 @@ static VALUE method_accountpam(VALUE self, VALUE servicename, VALUE username) {
162
246
 
163
247
  static VALUE method_getenvpam(VALUE self, VALUE servicename, VALUE username, VALUE password, VALUE envname, VALUE opensession, VALUE ruser, VALUE rhost) {
164
248
  pam_handle_t* pamh = NULL;
165
- const char *c_ret;
249
+ const char *c_ret=NULL;
166
250
  VALUE ruby_ret;
167
251
  unsigned int result = 0;
168
252
  struct pam_conv auth_c = {0,0};
@@ -176,7 +260,7 @@ static VALUE method_getenvpam(VALUE self, VALUE servicename, VALUE username, VAL
176
260
  rb_warn("INIT: %s", pam_strerror(pamh, result));
177
261
  return Qnil;
178
262
  }
179
-
263
+
180
264
  result = _start(pamh, &servicename, StringValueCStr(password), &ruser, &rhost);
181
265
  if(result != PAM_SUCCESS)
182
266
  return Qnil;
@@ -214,22 +298,22 @@ static VALUE method_getenvpam(VALUE self, VALUE servicename, VALUE username, VAL
214
298
  static VALUE method_listenvpam(VALUE self, VALUE servicename, VALUE username, VALUE password, VALUE opensession, VALUE ruser, VALUE rhost){
215
299
  pam_handle_t* pamh = NULL;
216
300
  unsigned int result=0;
217
- char *last;
218
- char **envlist;
219
- char **tmpenvlist;
301
+ char *last=NULL;
302
+ char **envlist=NULL;
303
+ char **tmpenvlist=NULL;
220
304
  VALUE ruby_ret;
221
305
  struct pam_conv auth_c = {0,0};
222
306
 
223
307
  Check_Type(username, T_STRING);
224
308
  Check_Type(password, T_STRING);
225
309
 
226
-
310
+
227
311
  result = pam_start(rpam_default_servicename, StringValueCStr(username), &auth_c, &pamh);
228
312
  if (result != PAM_SUCCESS) {
229
313
  rb_warn("INIT: %s", pam_strerror(pamh, result));
230
314
  return Qnil;
231
315
  }
232
-
316
+
233
317
  result = _start(pamh, &servicename, StringValueCStr(password), &ruser, &rhost);
234
318
  if(result != PAM_SUCCESS)
235
319
  return Qnil;
@@ -278,9 +362,8 @@ static VALUE method_listenvpam(VALUE self, VALUE servicename, VALUE username, VA
278
362
 
279
363
  void Init_rpam2(){
280
364
  rpam2 = rb_define_module("Rpam2");
281
- rb_define_singleton_method(rpam2, "_auth", method_authpam, 5);
282
- rb_define_singleton_method(rpam2, "account", method_accountpam, 2);
283
- rb_define_singleton_method(rpam2, "_getenv", method_getenvpam, 7);
284
- rb_define_singleton_method(rpam2, "_listenv", method_listenvpam, 6);
365
+ rb_define_singleton_method(rpam2, "_authc", method_authpam, 5);
366
+ rb_define_singleton_method(rpam2, "_accountc", method_accountpam, 2);
367
+ rb_define_singleton_method(rpam2, "_getenvc", method_getenvpam, 7);
368
+ rb_define_singleton_method(rpam2, "_listenvc", method_listenvpam, 6);
285
369
  }
286
-
data/lib/rpam2.rb CHANGED
@@ -1,42 +1,84 @@
1
+
2
+ require 'set'
3
+
4
+ require 'rpam2/rpam2'
5
+
1
6
  module Rpam2
2
- VERSION = 2.0
7
+ VERSION = 4.0
3
8
  class << self
9
+ attr_accessor :fake_data
10
+ @@fake_data = nil
11
+
4
12
  def auth(*args)
5
13
  case args.size
6
14
  when 3
7
- self._auth(*args, nil, nil)
15
+ _auth(*args, nil, nil)
8
16
  when 5
9
- self._auth(*args)
17
+ _auth(*args)
10
18
  else
11
19
  raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 3 or 5)"
12
20
  end
13
21
  end
22
+
23
+ def account(servicename, username)
24
+ _account(servicename, username)
25
+ end
26
+
14
27
  def getenv(*args)
15
28
  case args.size
16
29
  when 4
17
- self._getenv(*args, nil, nil, nil)
30
+ _getenv(*args, nil, nil, nil)
18
31
  when 5
19
- self._getenv(*args, nil, nil)
32
+ _getenv(*args, nil, nil)
20
33
  when 7
21
- self._getenv(*args)
34
+ _getenv(*args)
22
35
  else
23
36
  raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 4, 5 or 7)"
24
37
  end
25
38
  end
26
-
39
+
27
40
  def listenv(*args)
28
41
  case args.size
29
42
  when 3
30
- self._listenv(*args, nil, nil, nil)
43
+ _listenv(*args, nil, nil, nil)
31
44
  when 4
32
- self._listenv(*args, nil, nil)
45
+ _listenv(*args, nil, nil)
33
46
  when 6
34
- self._listenv(*args)
47
+ _listenv(*args)
35
48
  else
36
49
  raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 3, 4 or 6)"
37
50
  end
38
51
  end
52
+
53
+ private
54
+
55
+ def fake_compare(servicename, username)
56
+ return false unless self.fake_data
57
+ self.fake_data.fetch(:servicenames, Set.new).include?(servicename)
58
+ end
59
+
60
+ def _auth(servicename, username, password, ruser, rhost)
61
+ return _authc(servicename, username, password, ruser, rhost) unless fake_compare(servicename, username)
62
+ self.fake_data[:password] == password && self.fake_data.fetch(:usernames, Set.new).include?(username)
63
+ end
64
+
65
+ def _account(servicename, username)
66
+ return _accountc(servicename, username) unless self.fake_data && self.fake_data.fetch(:servicenames, Set.new).include?(servicename)
67
+ self.fake_data.fetch(:usernames, Set.new).include?(username)
68
+ end
69
+
70
+ def _getenv(servicename, username, password, opensession, varname, ruser, rhost)
71
+ return _getenvc(servicename, username, password, opensession, varname, ruser, rhost) unless fake_compare(servicename, username)
72
+ return nil unless self.fake_data.fetch(:usernames, Set.new).include?(username)
73
+ return nil if self.fake_data[:env].blank? || self.fake_data[:password] != password
74
+ self.fake_data[:env].fetch(varname, nil)
75
+ end
76
+
77
+ def _listenv(servicename, username, password, opensession, ruser, rhost)
78
+ return _listenvc(servicename, username, password, opensession, ruser, rhost) unless fake_compare(servicename, username)
79
+ return nil unless self.fake_data[:password] == password && self.fake_data.fetch(:usernames, Set.new).include?(username)
80
+ self.fake_data.fetch(:env, {})
81
+ end
39
82
  end
83
+ private_class_method :_authc, :_accountc, :_getenvc, :_listenvc
40
84
  end
41
-
42
- require "rpam2/rpam2"
data/rpam2.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "rpam2"
3
- s.version = "3.1.0"
3
+ s.version = "4.0.0"
4
4
  s.date = "2017-10-10"
5
5
  s.summary = "PAM integration with ruby."
6
6
  s.email = "devkral@web.de"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rpam2
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Kaftan
@@ -44,7 +44,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
44
44
  version: '0'
45
45
  requirements: []
46
46
  rubyforge_project:
47
- rubygems_version: 2.6.13
47
+ rubygems_version: 2.7.6
48
48
  signing_key:
49
49
  specification_version: 4
50
50
  summary: PAM integration with ruby.