netsoul 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +42 -0
- data/.pullreview.yml +77 -0
- data/.rspec +2 -0
- data/.rubocop.yml +24 -0
- data/.travis.yml +6 -0
- data/.versions.conf +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +86 -0
- data/Rakefile +18 -0
- data/bin/netsoul-ruby +122 -0
- data/ext/netsoul_kerberos/extconf.rb +10 -0
- data/ext/netsoul_kerberos/kerberos.c +206 -0
- data/ext/netsoul_kerberos/kerberos.h +58 -0
- data/ext/netsoul_kerberos/netsoul_kerberos.c +55 -0
- data/lib/netsoul/config.rb +41 -0
- data/lib/netsoul/errors.rb +6 -0
- data/lib/netsoul/location.rb +55 -0
- data/lib/netsoul/logging.rb +26 -0
- data/lib/netsoul/message.rb +143 -0
- data/lib/netsoul/version.rb +3 -0
- data/lib/netsoul.rb +6 -0
- data/netsoul.gemspec +39 -0
- metadata +190 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1fca4fc8cb31539dcadae7a5435367ccf62b30d8
|
4
|
+
data.tar.gz: 39ae71d45700d0a145d35a0c530471753e104e97
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d4b8ef7653cb49dba99db630aded565bfce9c4eb4aeca92e02ea74ffd112979f913bfd3be2e7ab8ef1d2f57772e8873514b912ca2c4eb7af264270a0c1b4814f
|
7
|
+
data.tar.gz: 44c2dfa0b942484e5d4c079d3b46bd5fe1614c36eb4d0f554aefc12eeee9d6de5e7df0360583dbfeed6e4977a370a1c9dcb1248391e68b21bdd562290c80612a
|
data/.gitignore
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
/.config
|
4
|
+
/coverage/
|
5
|
+
/InstalledFiles
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/test/tmp/
|
9
|
+
/test/version_tmp/
|
10
|
+
/tmp/
|
11
|
+
|
12
|
+
## Specific to RubyMotion:
|
13
|
+
.dat*
|
14
|
+
.repl_history
|
15
|
+
build/
|
16
|
+
|
17
|
+
## Documentation cache and generated files:
|
18
|
+
/.yardoc/
|
19
|
+
/_yardoc/
|
20
|
+
/doc/
|
21
|
+
/rdoc/
|
22
|
+
|
23
|
+
## Environment normalisation:
|
24
|
+
/.bundle/
|
25
|
+
/vendor/bundle
|
26
|
+
/lib/bundler/man/
|
27
|
+
|
28
|
+
# for a library or gem, you might want to ignore these files since the code is
|
29
|
+
# intended to run in multiple environments; otherwise, check them in:
|
30
|
+
# Gemfile.lock
|
31
|
+
# .ruby-version
|
32
|
+
# .ruby-gemset
|
33
|
+
|
34
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
35
|
+
.rvmrc
|
36
|
+
|
37
|
+
/.yardoc
|
38
|
+
/Gemfile.lock
|
39
|
+
/.idea/
|
40
|
+
/lib/*.so
|
41
|
+
/lib/*.dll
|
42
|
+
/lib/*.dylib
|
data/.pullreview.yml
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
---
|
2
|
+
rules:
|
3
|
+
ignore:
|
4
|
+
# - add_db_index
|
5
|
+
# - add_underscores_to_large_numeric
|
6
|
+
# - always_else_in_case
|
7
|
+
# - ambiguous_first_argument
|
8
|
+
# - assigned_but_unused_variable
|
9
|
+
# - assignment_in_conditional
|
10
|
+
# - avoid_copy_paste
|
11
|
+
# - avoid_empty_rescue_block
|
12
|
+
# - avoid_global_variable
|
13
|
+
# - avoid_similar_code
|
14
|
+
# - avoid_singleton_variable
|
15
|
+
# - avoid_using_curly_braces_for_multi-line_blocks
|
16
|
+
# - check_return_value_of_save
|
17
|
+
# - don_t_use_parentheses_around_the_condition
|
18
|
+
# - extra_blank_line_detected
|
19
|
+
# - extra_blank_line_detected_at_body_beginning
|
20
|
+
# - extra_blank_line_detected_at_body_end
|
21
|
+
# - favor_if_unless_for_single_line
|
22
|
+
# - improve_coverage_of_class
|
23
|
+
# - improve_coverage_of_method
|
24
|
+
# - improve_coverage_of_project
|
25
|
+
# - indent_when_as_deep_as_case
|
26
|
+
- missing_class_documentation
|
27
|
+
- missing_method_documentation
|
28
|
+
# - naming_convention_for_class
|
29
|
+
# - naming_convention_for_method
|
30
|
+
# - naming_convention_for_module
|
31
|
+
# - no_for_loop
|
32
|
+
# - no_instance_variable_in_partial
|
33
|
+
# - no_params_in_view
|
34
|
+
# - no_session_in_view
|
35
|
+
# - omit_parentheses_when_no_args
|
36
|
+
# - prefer_accolades_over_doend_for_single-line_blocks
|
37
|
+
# - prefer_map_over_collect
|
38
|
+
# - prefer_reduce_over_inject
|
39
|
+
# - prefer_ruby_19_new_hash_syntax
|
40
|
+
# - prefer_ruby_19_new_lambda_syntax
|
41
|
+
# - prefer_single_quoted_strings
|
42
|
+
- reduce_number_of_params
|
43
|
+
# - refactor_complex_class
|
44
|
+
# - refactor_complex_method
|
45
|
+
# - remove_trailing_whitespace
|
46
|
+
# - restrict_auto_generated_routes
|
47
|
+
# - shadowing_outer_local_variable
|
48
|
+
# - simplify_call_to_render
|
49
|
+
# - simplify_call_to_render_partial
|
50
|
+
# - space_between_curly_brace_and_pipe_missing
|
51
|
+
# - space_inside_closing_curly_brace_missing
|
52
|
+
# - space_inside_opening_curly_brace_missing
|
53
|
+
# - space_inside_parentheses_detected
|
54
|
+
# - space_inside_square_brackets_detected
|
55
|
+
# - space_missing_after_colon
|
56
|
+
# - space_missing_after_comma
|
57
|
+
# - space_missing_after_hash_sign
|
58
|
+
# - space_missing_after_semicolon
|
59
|
+
# - space_missing_inside_closing_curly_brace
|
60
|
+
# - space_missing_inside_opening_curly_brace
|
61
|
+
# - space_missing_to_left_of_parentheses
|
62
|
+
# - star_interpreted_as_argument_prefix
|
63
|
+
# - surrounding_space_missing_for_accolade
|
64
|
+
# - surrounding_space_missing_for_addition
|
65
|
+
# - surrounding_space_missing_for_arrow
|
66
|
+
# - surrounding_space_missing_for_assign
|
67
|
+
# - surrounding_space_missing_for_divide
|
68
|
+
# - surrounding_space_missing_for_equality
|
69
|
+
# - surrounding_space_missing_for_greater_than
|
70
|
+
# - surrounding_space_missing_for_incr
|
71
|
+
# - surrounding_space_missing_for_minus
|
72
|
+
# - surrounding_space_missing_for_multiplication
|
73
|
+
# - surrounding_space_missing_for_not_equal
|
74
|
+
# - surrounding_space_missing_for_t_square
|
75
|
+
# - use_a_logger
|
76
|
+
# - use_def_with_parentheses_when_there_are_arguments
|
77
|
+
# - uses_spaces_instead_of_tabs
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# Reference here: https://github.com/bbatsov/rubocop/blob/master/config/enabled.yml
|
2
|
+
|
3
|
+
Metrics/LineLength:
|
4
|
+
Description: 'Limit lines to 165 characters.'
|
5
|
+
Enabled: true
|
6
|
+
Max: 165
|
7
|
+
|
8
|
+
Metrics/MethodLength:
|
9
|
+
Description: 'Try to avoid methods longer than 50 lines of code.'
|
10
|
+
Enabled: true
|
11
|
+
Max: 50
|
12
|
+
|
13
|
+
Metrics/ClassLength:
|
14
|
+
Description: 'Try to avoid methods longer than 50 lines of code.'
|
15
|
+
Enabled: true
|
16
|
+
Max: 150
|
17
|
+
|
18
|
+
Style/Documentation:
|
19
|
+
Description: 'Document classes and non-namespace modules.'
|
20
|
+
Enabled: false
|
21
|
+
|
22
|
+
AllCops:
|
23
|
+
Excludes:
|
24
|
+
- 'bin/**'
|
data/.travis.yml
ADDED
data/.versions.conf
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Christian Kakesa
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
# Netsoul-Ruby (formerly libnetsoul-rb) [![Gem Version](https://badge.fury.io/rb/netsoul-ruby.svg)](http://badge.fury.io/rb/netsoul-ruby) [![Build Status](https://travis-ci.org/fenicks/netsoul-ruby.svg?branch=master)](https://travis-ci.org/fenicks/netsoul-ruby) [![Coverage Status](https://coveralls.io/repos/fenicks/netsoul-ruby/badge.svg?branch=master&service=github)](https://coveralls.io/github/fenicks/netsoul-ruby?branch=master)
|
2
|
+
|
3
|
+
This gem is a simple and efficient Netsoul client implementation written in Ruby.
|
4
|
+
You can use it as a Ruby gem in order to implement your own Netsoul client in Ruby or just use the provided Netsoul client.
|
5
|
+
|
6
|
+
*__[History]__: 8 years after writing my first ruby lines of code, I decide to rewrite this old own with all my Ruby backgrounds.*
|
7
|
+
|
8
|
+
## Features
|
9
|
+
|
10
|
+
* __MD5__ authentication
|
11
|
+
* __Kerberos__ (my own Ruby native extension) authentication. Something is wrong with kerberos server or gssapi __[work in progress]__
|
12
|
+
* Data transfert is supported **only for the library part, not the provided client**, use it at your own. _My academic account was closed when I tryed files transfert at school_.
|
13
|
+
* Identification Netsoul client is provided
|
14
|
+
* Netsoul message library: all netsoul DSL is covered by the 'netsoul/message' module
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
### On your desktop
|
19
|
+
|
20
|
+
```bash
|
21
|
+
gem install netsoul
|
22
|
+
```
|
23
|
+
|
24
|
+
### In your project
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
# Gemfile
|
28
|
+
gem 'netsoul', '~> 0.1'
|
29
|
+
```
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
# project.rb
|
33
|
+
require 'netsoul'
|
34
|
+
```
|
35
|
+
|
36
|
+
## Use the client
|
37
|
+
|
38
|
+
After installing the gem **netsoul**, call the client as described bellow.
|
39
|
+
|
40
|
+
```bash
|
41
|
+
netsoul-ruby -config netsoul-config.yml
|
42
|
+
```
|
43
|
+
|
44
|
+
### Example of _netsoul-config.yml_ file
|
45
|
+
|
46
|
+
#### Standard (MD5) authentication
|
47
|
+
|
48
|
+
```yaml
|
49
|
+
---|
|
50
|
+
:login: 'kakesa_c'
|
51
|
+
:socks_password: 'my socks password'
|
52
|
+
# :unix_password: 'unix password needed for kerberos authentication' # :auth_method must be set to :krb5
|
53
|
+
# :auth_method: :std # :std, :krb5
|
54
|
+
# :server_host: 'ns-server.epita.fr'
|
55
|
+
# :server_port: 4242
|
56
|
+
# :state: :none # :actif, :away, :connection, :idle, :lock, :server, :none
|
57
|
+
# :location: 'Home'
|
58
|
+
# :user_group: 'ETNA_2008'
|
59
|
+
```
|
60
|
+
|
61
|
+
#### Kerberos authentication
|
62
|
+
|
63
|
+
```yaml
|
64
|
+
---|
|
65
|
+
:login: 'kakesa_c'
|
66
|
+
:unix_password: 'unix password'
|
67
|
+
:auth_method: :krb5 # :std, :krb5
|
68
|
+
# :socks_password: 'my socks password'
|
69
|
+
# :server_host: 'ns-server.epita.fr'
|
70
|
+
# :server_port: 4242
|
71
|
+
# :state: :none # :actif, :away, :connection, :idle, :lock, :server, :none
|
72
|
+
# :location: 'Home'
|
73
|
+
# :user_group: 'ETNA_2008'
|
74
|
+
```
|
75
|
+
|
76
|
+
## Use the library in custom Netsoul Ruby client
|
77
|
+
|
78
|
+
__[TODO]__
|
79
|
+
|
80
|
+
## Contributing
|
81
|
+
|
82
|
+
1. Fork it ( https://github.com/fenicks/netsoul-ruby/fork )
|
83
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
84
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
85
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
86
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
require 'yard'
|
4
|
+
|
5
|
+
RSpec::Core::RakeTask.new('spec')
|
6
|
+
|
7
|
+
task default: :spec
|
8
|
+
|
9
|
+
require 'rake/extensiontask'
|
10
|
+
Rake::ExtensionTask.new 'netsoul_kerberos' do |ext|
|
11
|
+
ext.lib_dir = 'lib'
|
12
|
+
end
|
13
|
+
|
14
|
+
desc 'Generate documentation'
|
15
|
+
YARD::Rake::YardocTask.new do |t|
|
16
|
+
t.files = %w(lib/**/*.rb - LICENSE.txt)
|
17
|
+
t.options = %w(--main README.md --no-private --protected)
|
18
|
+
end
|
data/bin/netsoul-ruby
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- encoding: binary -*-
|
3
|
+
lib = File.expand_path('../../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift lib unless $LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
require 'base64'
|
7
|
+
require 'digest/md5'
|
8
|
+
require 'netsoul'
|
9
|
+
require 'socket'
|
10
|
+
require 'uri'
|
11
|
+
|
12
|
+
module Netsoul
|
13
|
+
class Client
|
14
|
+
include Logging
|
15
|
+
|
16
|
+
attr_reader :started
|
17
|
+
|
18
|
+
def initialize(*args)
|
19
|
+
opts = args.last.is_a?(Hash) ? args.last : {}
|
20
|
+
@config = Config.new(opts)
|
21
|
+
@started = false
|
22
|
+
end
|
23
|
+
|
24
|
+
def auth_ag
|
25
|
+
sock_send(Message.auth_ag)
|
26
|
+
fail Netsoul::IdentificationError, 'Identification failed.'.freeze unless sock_get.split(' ')[1] == '002'.freeze
|
27
|
+
end
|
28
|
+
private :auth_ag
|
29
|
+
|
30
|
+
def auth_method
|
31
|
+
if @config.auth_method == :krb5
|
32
|
+
sock_send(Message.kerberos_auth(@config))
|
33
|
+
else
|
34
|
+
sock_send(Message.standard_auth(@config))
|
35
|
+
end
|
36
|
+
fail Netsoul::AuthenticationError, 'Authentication failed.'.freeze unless sock_get.split(' ')[1] == '002'
|
37
|
+
end
|
38
|
+
private :auth_method
|
39
|
+
|
40
|
+
def auth_status
|
41
|
+
sock_send(Message.attach)
|
42
|
+
sock_send(Message.user_state(@config.state, Time.now.to_i))
|
43
|
+
end
|
44
|
+
private :auth_status
|
45
|
+
|
46
|
+
def connect
|
47
|
+
@sock = TCPSocket.new(@config.server_host, @config.server_port)
|
48
|
+
fail Netsoul::SocketError, 'Could not open a socket. Connection is unavailable.'.freeze unless @sock
|
49
|
+
|
50
|
+
_cmd, _socket_num, md5_hash, client_ip, client_port, _server_timestamp = sock_get.split
|
51
|
+
@config.build_user_connection_info md5_hash: md5_hash, client_ip: client_ip, client_port: client_port
|
52
|
+
|
53
|
+
auth_ag
|
54
|
+
auth_method
|
55
|
+
auth_status
|
56
|
+
@started = true
|
57
|
+
end
|
58
|
+
|
59
|
+
def disconnect
|
60
|
+
sock_send(Message.ns_exit)
|
61
|
+
ensure
|
62
|
+
sock_close
|
63
|
+
end
|
64
|
+
|
65
|
+
def sock_send(str)
|
66
|
+
log :info, "[send] #{str.chomp}"
|
67
|
+
@sock.puts str
|
68
|
+
end
|
69
|
+
|
70
|
+
def sock_get
|
71
|
+
res = @sock.gets
|
72
|
+
log :info, "[get ] #{res.chomp}"
|
73
|
+
res
|
74
|
+
end
|
75
|
+
|
76
|
+
def sock_close
|
77
|
+
@started = false
|
78
|
+
@sock.close
|
79
|
+
rescue
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
if __FILE__ == $PROGRAM_NAME
|
86
|
+
$stderr.sync = true
|
87
|
+
require 'optparse'
|
88
|
+
require 'yaml'
|
89
|
+
|
90
|
+
options = {}
|
91
|
+
OptionParser.new do |opts|
|
92
|
+
opts.banner = 'Usage: netsoul-ruby [options]'.freeze
|
93
|
+
opts.separator "\nNetsoul-Ruby options:".freeze
|
94
|
+
opts.on('-c'.freeze, '--config FILE'.freeze, 'Configuration file in YAML'.freeze) do |file|
|
95
|
+
options[:config] = file
|
96
|
+
unless File.file?(options[:config])
|
97
|
+
puts '[ERROR] Configuration is not a valid file'
|
98
|
+
exit
|
99
|
+
end
|
100
|
+
options[:user_opts] = YAML.load_file(options[:config])
|
101
|
+
end
|
102
|
+
opts.on('-h', '--help', 'Display this screen') do
|
103
|
+
puts opts
|
104
|
+
exit
|
105
|
+
end
|
106
|
+
end.parse!
|
107
|
+
|
108
|
+
unless options.include?(:config)
|
109
|
+
puts '[ERROR] Configuration file is not provided'
|
110
|
+
exit
|
111
|
+
end
|
112
|
+
|
113
|
+
c = Netsoul::Client.new options[:user_opts]
|
114
|
+
c.connect
|
115
|
+
if c.started
|
116
|
+
loop do
|
117
|
+
res = c.sock_get
|
118
|
+
c.sock_send res if res.to_s.match(/^ping.*/)
|
119
|
+
sleep 1
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'mkmf'
|
2
|
+
|
3
|
+
have_library('krb5', 'krb5_init_context')
|
4
|
+
have_library('gssapi_krb5', 'gss_init_sec_context')
|
5
|
+
have_header('string.h')
|
6
|
+
have_header('krb5.h')
|
7
|
+
have_header('gssapi/gssapi.h')
|
8
|
+
have_header('gssapi/gssapi_krb5.h')
|
9
|
+
|
10
|
+
create_makefile('netsoul_kerberos')
|
@@ -0,0 +1,206 @@
|
|
1
|
+
/*
|
2
|
+
** This file is part of RubySoul project.
|
3
|
+
**
|
4
|
+
** Test for the kerberos authentication.
|
5
|
+
**
|
6
|
+
** @author Christian KAKESA <christian.kakesa@gmail.com>
|
7
|
+
*/
|
8
|
+
|
9
|
+
#include <stdio.h>
|
10
|
+
#include <stdlib.h>
|
11
|
+
#include <string.h>
|
12
|
+
#include <krb5.h>
|
13
|
+
#include <gssapi/gssapi.h>
|
14
|
+
#include <gssapi/gssapi_krb5.h>
|
15
|
+
|
16
|
+
#include "kerberos.h"
|
17
|
+
|
18
|
+
void display_status(k_data_t *data)
|
19
|
+
{
|
20
|
+
OM_uint32 minor, status;
|
21
|
+
gss_buffer_desc msg;
|
22
|
+
|
23
|
+
gss_display_status(&minor, data->min, GSS_C_GSS_CODE, GSS_C_NO_OID, &status, &msg);
|
24
|
+
if (msg.value) puts(msg.value);
|
25
|
+
}
|
26
|
+
|
27
|
+
krb5_error_code get_new_tickets( k_data_t *data,
|
28
|
+
krb5_context context,
|
29
|
+
krb5_principal principal,
|
30
|
+
krb5_ccache ccache)
|
31
|
+
{
|
32
|
+
krb5_error_code ret;
|
33
|
+
krb5_get_init_creds_opt opt;
|
34
|
+
krb5_creds cred;
|
35
|
+
// char * password = NULL;
|
36
|
+
|
37
|
+
memset(&cred, 0, sizeof(cred));
|
38
|
+
krb5_get_init_creds_opt_init (&opt);
|
39
|
+
ret = krb5_get_init_creds_password(context,
|
40
|
+
&cred,
|
41
|
+
principal,
|
42
|
+
data->unix_pass,
|
43
|
+
krb5_prompter_posix,
|
44
|
+
NULL,
|
45
|
+
0,
|
46
|
+
NULL,
|
47
|
+
&opt);
|
48
|
+
if (ret == KRB5_LIBOS_PWDINTR ||
|
49
|
+
ret == KRB5KRB_AP_ERR_MODIFIED ||
|
50
|
+
ret == KRB5KRB_AP_ERR_MODIFIED)
|
51
|
+
return (1);
|
52
|
+
else if (ret)
|
53
|
+
return (2);
|
54
|
+
if (krb5_cc_initialize(context, ccache, cred.client))
|
55
|
+
return (3);
|
56
|
+
if (krb5_cc_store_cred(context, ccache, &cred))
|
57
|
+
return (3);
|
58
|
+
//krb5_free_creds_contents(context, &cred);
|
59
|
+
return (0);
|
60
|
+
}
|
61
|
+
|
62
|
+
int my_init(k_data_t *data)
|
63
|
+
{
|
64
|
+
krb5_error_code ret;
|
65
|
+
krb5_context context;
|
66
|
+
krb5_ccache ccache;
|
67
|
+
krb5_principal principal;
|
68
|
+
|
69
|
+
if (krb5_init_context(&context))
|
70
|
+
return (1);
|
71
|
+
|
72
|
+
if (!data->login ||
|
73
|
+
krb5_build_principal(context, &principal, sizeof(NS_REALM) - 1, NS_REALM, data->login, NULL))
|
74
|
+
return (1);
|
75
|
+
if (krb5_cc_default(context, &ccache))
|
76
|
+
return (1);
|
77
|
+
|
78
|
+
ret = get_new_tickets(data, context, principal, ccache);
|
79
|
+
krb5_cc_close(context, ccache);
|
80
|
+
krb5_free_principal(context, principal);
|
81
|
+
krb5_free_context(context);
|
82
|
+
return (ret);
|
83
|
+
}
|
84
|
+
|
85
|
+
void import_name(k_data_t *data)
|
86
|
+
{
|
87
|
+
OM_uint32 min;
|
88
|
+
OM_uint32 maj;
|
89
|
+
gss_buffer_desc buf;
|
90
|
+
|
91
|
+
buf.value = (unsigned char *) strdup(NS_SERVICE_NAME);
|
92
|
+
buf.length = strlen((const char*)buf.value) + 1;
|
93
|
+
maj = gss_import_name(&min, &buf, GSS_C_NT_HOSTBASED_SERVICE, &data->gss_name);
|
94
|
+
|
95
|
+
if (maj != GSS_S_COMPLETE)
|
96
|
+
display_status(data);
|
97
|
+
}
|
98
|
+
|
99
|
+
void init_context(k_data_t *data)
|
100
|
+
{
|
101
|
+
OM_uint32 maj;
|
102
|
+
/* gss_buffer_t itoken = GSS_C_NO_BUFFER; */
|
103
|
+
krb5_enctype etypes[] = { ENCTYPE_DES3_CBC_SHA1, ENCTYPE_NULL };
|
104
|
+
int etype_count = sizeof(etypes) / sizeof(*etypes);
|
105
|
+
gss_cred_id_t credh;
|
106
|
+
|
107
|
+
maj = gss_acquire_cred( &data->min,
|
108
|
+
GSS_C_NO_NAME,
|
109
|
+
GSS_C_INDEFINITE,
|
110
|
+
GSS_C_NO_OID_SET,
|
111
|
+
GSS_C_INITIATE,
|
112
|
+
&credh,
|
113
|
+
NULL,
|
114
|
+
NULL);
|
115
|
+
if (maj != GSS_S_COMPLETE)
|
116
|
+
{
|
117
|
+
display_status(data);
|
118
|
+
return;
|
119
|
+
}
|
120
|
+
maj = gss_krb5_set_allowable_enctypes(&data->min, credh, etype_count, etypes);
|
121
|
+
if (maj != GSS_S_COMPLETE)
|
122
|
+
{
|
123
|
+
display_status(data);
|
124
|
+
return;
|
125
|
+
}
|
126
|
+
data->ctx = GSS_C_NO_CONTEXT;
|
127
|
+
maj = gss_init_sec_context( &data->min,
|
128
|
+
credh,
|
129
|
+
&data->ctx,
|
130
|
+
data->gss_name,
|
131
|
+
GSS_C_NO_OID,
|
132
|
+
GSS_C_CONF_FLAG,
|
133
|
+
0,
|
134
|
+
GSS_C_NO_CHANNEL_BINDINGS,
|
135
|
+
data->itoken,
|
136
|
+
NULL,
|
137
|
+
&data->otoken,
|
138
|
+
NULL,
|
139
|
+
NULL);
|
140
|
+
|
141
|
+
if (data->maj != GSS_S_COMPLETE)
|
142
|
+
display_status(data);
|
143
|
+
}
|
144
|
+
|
145
|
+
int check_tokens(k_data_t *data)
|
146
|
+
{
|
147
|
+
import_name(data);
|
148
|
+
init_context(data);
|
149
|
+
|
150
|
+
if (!data->otoken.value)
|
151
|
+
{
|
152
|
+
my_init(data);
|
153
|
+
import_name(data);
|
154
|
+
init_context(data);
|
155
|
+
}
|
156
|
+
if (data->otoken.value)
|
157
|
+
return (1);
|
158
|
+
|
159
|
+
return (0);
|
160
|
+
}
|
161
|
+
|
162
|
+
/**
|
163
|
+
* Encode string in base64
|
164
|
+
*/
|
165
|
+
unsigned char * base64_encode(const unsigned char *src, size_t len, size_t *out_len)
|
166
|
+
{
|
167
|
+
unsigned char *out, *pos;
|
168
|
+
const unsigned char *end, *in;
|
169
|
+
size_t olen;
|
170
|
+
int line_len;
|
171
|
+
const unsigned char base64_table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
172
|
+
|
173
|
+
olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
|
174
|
+
out = malloc(olen);
|
175
|
+
if (out == NULL)
|
176
|
+
return NULL;
|
177
|
+
|
178
|
+
end = src + len;
|
179
|
+
in = src;
|
180
|
+
pos = out;
|
181
|
+
while (end - in >= 3) {
|
182
|
+
*pos++ = base64_table[in[0] >> 2];
|
183
|
+
*pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
|
184
|
+
*pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
|
185
|
+
*pos++ = base64_table[in[2] & 0x3f];
|
186
|
+
in += 3;
|
187
|
+
}
|
188
|
+
|
189
|
+
if (end - in) {
|
190
|
+
*pos++ = base64_table[in[0] >> 2];
|
191
|
+
if (end - in == 1) {
|
192
|
+
*pos++ = base64_table[(in[0] & 0x03) << 4];
|
193
|
+
*pos++ = '=';
|
194
|
+
} else {
|
195
|
+
*pos++ = base64_table[((in[0] & 0x03) << 4) |
|
196
|
+
(in[1] >> 4)];
|
197
|
+
*pos++ = base64_table[(in[1] & 0x0f) << 2];
|
198
|
+
}
|
199
|
+
*pos++ = '=';
|
200
|
+
line_len += 4;
|
201
|
+
}
|
202
|
+
|
203
|
+
if (out_len)
|
204
|
+
*out_len = pos - out;
|
205
|
+
return out;
|
206
|
+
}
|
@@ -0,0 +1,58 @@
|
|
1
|
+
/*
|
2
|
+
** This file is part of RubySoul project.
|
3
|
+
**
|
4
|
+
** Test for the kerberos authentication.
|
5
|
+
**
|
6
|
+
** @author Christian KAKESA <christian.kakesa@gmail.com>
|
7
|
+
*/
|
8
|
+
|
9
|
+
#ifndef __KERBEROS_H_
|
10
|
+
#define __KERBEROS_H_
|
11
|
+
|
12
|
+
#include <stdio.h>
|
13
|
+
#include <stdlib.h>
|
14
|
+
#include <string.h>
|
15
|
+
#include <krb5.h>
|
16
|
+
#include <gssapi/gssapi.h>
|
17
|
+
#include <gssapi/gssapi_krb5.h>
|
18
|
+
|
19
|
+
#define NS_SERVICE_NAME "host@ns-server.epitech.net"
|
20
|
+
#define NS_REALM "EPITECH.NET"
|
21
|
+
|
22
|
+
typedef struct k_data
|
23
|
+
{
|
24
|
+
char* login;
|
25
|
+
char* unix_pass;
|
26
|
+
OM_uint32 min;
|
27
|
+
OM_uint32 maj;
|
28
|
+
gss_name_t gss_name;
|
29
|
+
gss_ctx_id_t ctx;
|
30
|
+
gss_buffer_t itoken;
|
31
|
+
gss_buffer_desc otoken;
|
32
|
+
} k_data_t;
|
33
|
+
|
34
|
+
void
|
35
|
+
display_status(k_data_t *data);
|
36
|
+
|
37
|
+
krb5_error_code
|
38
|
+
get_new_tickets( k_data_t *data,
|
39
|
+
krb5_context context,
|
40
|
+
krb5_principal principal,
|
41
|
+
krb5_ccache ccache);
|
42
|
+
|
43
|
+
int
|
44
|
+
my_init(k_data_t *data);
|
45
|
+
|
46
|
+
void
|
47
|
+
import_name(k_data_t *data);
|
48
|
+
|
49
|
+
void
|
50
|
+
init_context(k_data_t *data);
|
51
|
+
|
52
|
+
int
|
53
|
+
check_tokens(k_data_t *data);
|
54
|
+
|
55
|
+
unsigned char *
|
56
|
+
base64_encode(const unsigned char *src, size_t len, size_t *out_len);
|
57
|
+
|
58
|
+
#endif /* !__KERBEROS_H_ */
|
@@ -0,0 +1,55 @@
|
|
1
|
+
/*
|
2
|
+
** This file is part of RubySoul project.
|
3
|
+
**
|
4
|
+
** Test for the kerberos authentication.
|
5
|
+
**
|
6
|
+
** @author Christian KAKESA <christian.kakesa@gmail.com>
|
7
|
+
*/
|
8
|
+
|
9
|
+
#include <ruby.h>
|
10
|
+
|
11
|
+
#include "kerberos.h"
|
12
|
+
|
13
|
+
VALUE cNetsoulKerberos;
|
14
|
+
|
15
|
+
static VALUE k_init(VALUE self)
|
16
|
+
{
|
17
|
+
rb_define_attr(cNetsoulKerberos, "login", 1, 1);
|
18
|
+
rb_define_attr(cNetsoulKerberos, "password", 1, 1);
|
19
|
+
rb_define_attr(cNetsoulKerberos, "token", 1, 0);
|
20
|
+
rb_define_attr(cNetsoulKerberos, "token_base64", 1, 0);
|
21
|
+
return self;
|
22
|
+
}
|
23
|
+
|
24
|
+
static VALUE k_build_token(VALUE self, VALUE login, VALUE password)
|
25
|
+
{
|
26
|
+
k_data_t *data;
|
27
|
+
unsigned char *token_base64;
|
28
|
+
unsigned char *token;
|
29
|
+
size_t elen;
|
30
|
+
|
31
|
+
data = calloc(1, sizeof (k_data_t));
|
32
|
+
data->login = (char*)login;
|
33
|
+
data->unix_pass = (char*)password;
|
34
|
+
data->itoken = GSS_C_NO_BUFFER;
|
35
|
+
if (check_tokens(data) != 1)
|
36
|
+
return Qfalse;
|
37
|
+
|
38
|
+
token = (unsigned char*)strdup(data->otoken.value);
|
39
|
+
token_base64 = base64_encode((const unsigned char*)data->otoken.value, data->otoken.length, &elen);
|
40
|
+
rb_iv_set(self, "@login", login);
|
41
|
+
rb_iv_set(self, "@password", password);
|
42
|
+
rb_iv_set(self, "@token", rb_str_new2((const char*)token));
|
43
|
+
rb_iv_set(self, "@token_base64", rb_str_new2((const char*)token_base64));
|
44
|
+
free(token);
|
45
|
+
free(token_base64);
|
46
|
+
free(data);
|
47
|
+
return Qtrue;
|
48
|
+
}
|
49
|
+
|
50
|
+
void Init_netsoul_kerberos()
|
51
|
+
{
|
52
|
+
cNetsoulKerberos = rb_define_class("NetsoulKerberos", rb_cObject);
|
53
|
+
rb_define_method(cNetsoulKerberos, "initialize", k_init, 0);
|
54
|
+
rb_define_method(cNetsoulKerberos, "build_token", k_build_token, 2);
|
55
|
+
}
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Netsoul
|
2
|
+
class Config
|
3
|
+
AUTH_METHODS = [:std, :krb5].freeze
|
4
|
+
USER_STATES = [:actif, :away, :connection, :idle, :lock, :server, :none].freeze
|
5
|
+
VALID_USER_CONNECTION_INFO = [:md5_hash, :client_ip, :client_port].freeze
|
6
|
+
|
7
|
+
attr_accessor :server_host,
|
8
|
+
:server_port,
|
9
|
+
:login,
|
10
|
+
:socks_password,
|
11
|
+
:unix_password,
|
12
|
+
:auth_method,
|
13
|
+
:state,
|
14
|
+
:location,
|
15
|
+
:user_group,
|
16
|
+
:user_connection_info # Not used in configuration file
|
17
|
+
|
18
|
+
attr_reader :client_name
|
19
|
+
|
20
|
+
# rubocop:disable Metrics/AbcSize
|
21
|
+
def initialize(opts = {})
|
22
|
+
@server_host = opts.fetch(:server_host, 'ns-server.epita.fr'.freeze)
|
23
|
+
@server_port = Integer(opts.fetch(:server_port, 4242))
|
24
|
+
@login = opts.fetch(:login, 'ionis'.freeze)
|
25
|
+
@socks_password = opts.fetch(:socks_password, 'socks_password'.freeze)
|
26
|
+
@unix_password = opts.fetch(:unix_password, 'unix_password'.freeze)
|
27
|
+
@auth_method = AUTH_METHODS.include?(opts[:auth_method]) ? opts[:auth_method] : :std
|
28
|
+
@state = USER_STATES.include?(opts[:state]) ? opts[:state] : :none
|
29
|
+
@location = opts.fetch(:location, 'Home'.freeze)
|
30
|
+
@user_group = opts.fetch(:user_group, 'ETNA_2008'.freeze)
|
31
|
+
@user_connection_info = {}
|
32
|
+
|
33
|
+
@client_name = opts.fetch(:client_name, '(Netsoul-Ruby) -> { Christian Kakesa, since 2009}'.freeze)
|
34
|
+
end
|
35
|
+
|
36
|
+
def build_user_connection_info(opts = {})
|
37
|
+
return unless opts.is_a?(Hash)
|
38
|
+
opts.each { |k, v| @user_connection_info[k] = v if VALID_USER_CONNECTION_INFO.include?(k) }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Netsoul
|
2
|
+
class Location
|
3
|
+
class << self
|
4
|
+
def get(ip)
|
5
|
+
locations.each do |key, val|
|
6
|
+
res = ip.match(/^#{val}/)
|
7
|
+
if res
|
8
|
+
res = "#{key}"
|
9
|
+
return res
|
10
|
+
end
|
11
|
+
end
|
12
|
+
'ext'.freeze
|
13
|
+
end
|
14
|
+
|
15
|
+
# rubocop:disable Metrics/AbcSize
|
16
|
+
def locations
|
17
|
+
{
|
18
|
+
'lab-cisco-mid-sr': '10.251.'.freeze,
|
19
|
+
etna: '10.245.'.freeze,
|
20
|
+
lse: '10.227.42.'.freeze,
|
21
|
+
'sda-1': '10.227.4.'.freeze,
|
22
|
+
lab: '10.227.'.freeze,
|
23
|
+
'lab-tcom': '10.226.7.'.freeze,
|
24
|
+
'lab-acu': '10.226.6.'.freeze,
|
25
|
+
'lab-console': '10.226.5.'.freeze,
|
26
|
+
'lab-mspe': '10.226.'.freeze,
|
27
|
+
epitanim: '10.225.19.'.freeze,
|
28
|
+
epidemic: '10.225.18.'.freeze,
|
29
|
+
'sda-2': '10.225.10.'.freeze,
|
30
|
+
cycom: '10.225.8.'.freeze,
|
31
|
+
epx: '10.225.7.'.freeze,
|
32
|
+
prologin: '10.225.6.'.freeze,
|
33
|
+
nomad: '10.225.2.'.freeze,
|
34
|
+
assos: '10.225.'.freeze,
|
35
|
+
sda: '10.224.14.'.freeze,
|
36
|
+
www: '10.223.106.'.freeze,
|
37
|
+
episport: '10.223.104.'.freeze,
|
38
|
+
epicom: '10.223.103.'.freeze,
|
39
|
+
'bde-epita': '10.223.100.'.freeze,
|
40
|
+
omatis: '10.223.42.'.freeze,
|
41
|
+
ipsa: '10.223.15.'.freeze,
|
42
|
+
lrde: '10.223.13.'.freeze,
|
43
|
+
cvi: '10.223.7.'.freeze,
|
44
|
+
epi: '10.223.1.'.freeze,
|
45
|
+
pasteur: '10.223.'.freeze,
|
46
|
+
bocal: '10.42.42.'.freeze,
|
47
|
+
sm: '10.42.'.freeze,
|
48
|
+
vpn: '10.10.'.freeze,
|
49
|
+
adm: '10.1.'.freeze,
|
50
|
+
epita: '10.'.freeze
|
51
|
+
}
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module Netsoul
|
4
|
+
module Logging # :nodoc:
|
5
|
+
PREFIX = '[Netsoul-Ruby]'.freeze
|
6
|
+
|
7
|
+
class << self
|
8
|
+
attr_writer :logger
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.logger
|
12
|
+
@logger ||= ::Logger.new(STDERR).tap do |logger|
|
13
|
+
logger.level = Logger::INFO
|
14
|
+
logger.formatter = proc do |severity, datetime, _progname, msg|
|
15
|
+
"#{severity} [#{datetime.strftime('%Y-%m-%d %H:%M:%S.%L'.freeze)}] #{msg}\n"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def log(level, message)
|
23
|
+
Netsoul::Logging.logger.send(level.to_sym, "#{PREFIX} #{message}") if Netsoul::Logging.logger
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
module Netsoul
|
2
|
+
class Message
|
3
|
+
class << self
|
4
|
+
def _standard_auth_string(c)
|
5
|
+
str = "#{c.user_connection_info[:md5_hash]}"
|
6
|
+
str << "-#{c.user_connection_info[:client_ip]}"
|
7
|
+
str << "/#{c.user_connection_info[:client_port]}#{c.socks_password}"
|
8
|
+
Digest::MD5.hexdigest(str)
|
9
|
+
end
|
10
|
+
|
11
|
+
def standard_auth(config)
|
12
|
+
login = config.login
|
13
|
+
client_ip = config.user_connection_info[:client_ip]
|
14
|
+
user_custom_location = config.location
|
15
|
+
location = Message.escape(Location.get(client_ip) == 'ext'.freeze ? user_custom_location : Location.get(client_ip))
|
16
|
+
client_name = Message.escape(config.client_name)
|
17
|
+
"ext_user_log #{login} #{_standard_auth_string(config)} #{client_name} #{location}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def _kerberos_get
|
21
|
+
require 'netsoul_kerberos'
|
22
|
+
@netsoul_kerberos ||= NetsoulKerberos.new
|
23
|
+
rescue LoadError => e
|
24
|
+
raise Netsoul::Error, "NetsoulKerberos library not found: #{e}.".freeze
|
25
|
+
end
|
26
|
+
|
27
|
+
def _kerberos_auth_klog(config)
|
28
|
+
location = Message.escape(config.location)
|
29
|
+
user_group = Message.escape(config.user_group)
|
30
|
+
client_name = Message.escape(config.client_name)
|
31
|
+
"ext_user_klog #{_kerberos_get.token_base64.slice(0, 812)} #{Message.escape(RUBY_PLATFORM)} #{location} #{user_group} #{client_name}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def kerberos_auth(config)
|
35
|
+
unless _kerberos_get.build_token(config.login, config.unix_password)
|
36
|
+
fail Netsoul::Error, 'Impossible to retrieve the kerberos token.'.freeze
|
37
|
+
end
|
38
|
+
_kerberos_auth_klog(config)
|
39
|
+
end
|
40
|
+
|
41
|
+
def auth_ag
|
42
|
+
'auth_ag ext_user none -'.freeze
|
43
|
+
end
|
44
|
+
|
45
|
+
def send_message(user, msg)
|
46
|
+
"user_cmd msg_user #{user} msg #{Message.escape(msg.to_s)}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def start_writing_to_user(user)
|
50
|
+
"user_cmd msg_user #{user} dotnetSoul_UserTyping null"
|
51
|
+
end
|
52
|
+
|
53
|
+
def stop_writing_to_user(user)
|
54
|
+
"user_cmd msg_user #{user} dotnetSoul_UserCancelledTyping null"
|
55
|
+
end
|
56
|
+
|
57
|
+
def list_users(user_list)
|
58
|
+
"list_users {#{user_list}}"
|
59
|
+
end
|
60
|
+
|
61
|
+
def who_users(user_list)
|
62
|
+
"user_cmd who {#{user_list}}"
|
63
|
+
end
|
64
|
+
|
65
|
+
def watch_users(user_list)
|
66
|
+
"user_cmd watch_log_user {#{user_list}}"
|
67
|
+
end
|
68
|
+
|
69
|
+
def attach
|
70
|
+
'user_cmd attach'.freeze
|
71
|
+
end
|
72
|
+
|
73
|
+
def user_state(state, timestamp)
|
74
|
+
"user_cmd state #{state}:#{timestamp}"
|
75
|
+
end
|
76
|
+
|
77
|
+
def user_data(data)
|
78
|
+
"user_cmd user_data #{Message.escape(data.to_s)}"
|
79
|
+
end
|
80
|
+
|
81
|
+
def xfer(user, id, filename, size, desc)
|
82
|
+
"user_cmd msg_user #{user} desoul_ns_xfer #{Message.escape("#{id} #{filename} #{size} #{desc}")}"
|
83
|
+
end
|
84
|
+
|
85
|
+
def desoul_ns_xfer(user, id, filename, size, desc)
|
86
|
+
xfer(user, id, filename, size, desc)
|
87
|
+
end
|
88
|
+
|
89
|
+
def xfer_accept(user, id)
|
90
|
+
"user_cmd msg_user #{user} desoul_ns_xfer_accept #{id}"
|
91
|
+
end
|
92
|
+
|
93
|
+
def desoul_ns_xfer_accept(user, id)
|
94
|
+
xfer_accept(user, id)
|
95
|
+
end
|
96
|
+
|
97
|
+
def xfer_data(user, id, data)
|
98
|
+
"user_cmd msg_user #{user} desoul_ns_xfer_data #{Message.escape("#{id} #{Base64.b64encode(data.to_s, data.to_s.length)}")}"
|
99
|
+
end
|
100
|
+
|
101
|
+
def desoul_ns_xfer_data(user, id, data)
|
102
|
+
xfer_data(user, id, data)
|
103
|
+
end
|
104
|
+
|
105
|
+
def xfer_cancel(user, id)
|
106
|
+
"user_cmd msg_user #{user} desoul_ns_xfer_cancel #{id}"
|
107
|
+
end
|
108
|
+
|
109
|
+
def desoul_ns_xfer_cancel(user, id)
|
110
|
+
xfer_cancel(user, id)
|
111
|
+
end
|
112
|
+
|
113
|
+
def ping
|
114
|
+
'pong'.freeze
|
115
|
+
end
|
116
|
+
|
117
|
+
def ns_exit
|
118
|
+
'exit'.freeze
|
119
|
+
end
|
120
|
+
|
121
|
+
def escape(str)
|
122
|
+
str = URI.escape(str, Regexp.new("#{URI::PATTERN::ALNUM}[:graph:][:punct:][:cntrl:][:print:][:blank:]", false, 'N'.freeze))
|
123
|
+
URI.escape(str, Regexp.new("[^#{URI::PATTERN::ALNUM}]", false, 'N'.freeze))
|
124
|
+
end
|
125
|
+
|
126
|
+
def unescape(str)
|
127
|
+
URI.unescape str
|
128
|
+
end
|
129
|
+
|
130
|
+
def ltrim(str)
|
131
|
+
str.to_s.gsub(/^\s+/, ''.freeze)
|
132
|
+
end
|
133
|
+
|
134
|
+
def rtrim(str)
|
135
|
+
str.to_s.gsub(/\s+$/, ''.freeze)
|
136
|
+
end
|
137
|
+
|
138
|
+
def trim(str)
|
139
|
+
rtrim(ltrim(str.to_s))
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
data/lib/netsoul.rb
ADDED
data/netsoul.gemspec
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'netsoul/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'netsoul'
|
8
|
+
spec.version = Netsoul::VERSION
|
9
|
+
spec.authors = ['Christian Kakesa']
|
10
|
+
spec.email = ['christian.kakesa@gmail.com']
|
11
|
+
|
12
|
+
spec.summary = 'Netsoul client and library for ruby.'
|
13
|
+
spec.description = spec.summary
|
14
|
+
spec.homepage = 'https://github.com/fenicks/netsoul-ruby'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
18
|
+
# delete this section to allow pushing this gem to any host.
|
19
|
+
# if spec.respond_to?(:metadata)
|
20
|
+
# spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
21
|
+
# else
|
22
|
+
# fail 'RubyGems 2.0 or newer is required to protect against public gem pushes.'
|
23
|
+
# end
|
24
|
+
|
25
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
26
|
+
spec.bindir = 'bin'
|
27
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
28
|
+
spec.require_paths = %w(lib ext bin)
|
29
|
+
spec.extensions = ['ext/netsoul_kerberos/extconf.rb']
|
30
|
+
|
31
|
+
spec.add_development_dependency 'bundler', '~> 1.7', '>= 1.7.0'
|
32
|
+
spec.add_development_dependency 'rake', '~> 0'
|
33
|
+
spec.add_development_dependency 'rubocop', '~> 0'
|
34
|
+
spec.add_development_dependency 'rspec', '~> 3.3'
|
35
|
+
spec.add_development_dependency 'simplecov', '~> 0'
|
36
|
+
spec.add_development_dependency 'coveralls', '~> 0'
|
37
|
+
spec.add_development_dependency 'yard', '~> 0'
|
38
|
+
spec.add_development_dependency 'rake-compiler', '~> 0.9.5'
|
39
|
+
end
|
metadata
ADDED
@@ -0,0 +1,190 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: netsoul
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Christian Kakesa
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-01-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.7.0
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.7'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.7.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: rake
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rubocop
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rspec
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '3.3'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '3.3'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: simplecov
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: coveralls
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: yard
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - "~>"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: rake-compiler
|
119
|
+
requirement: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - "~>"
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: 0.9.5
|
124
|
+
type: :development
|
125
|
+
prerelease: false
|
126
|
+
version_requirements: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - "~>"
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: 0.9.5
|
131
|
+
description: Netsoul client and library for ruby.
|
132
|
+
email:
|
133
|
+
- christian.kakesa@gmail.com
|
134
|
+
executables:
|
135
|
+
- netsoul-ruby
|
136
|
+
extensions:
|
137
|
+
- ext/netsoul_kerberos/extconf.rb
|
138
|
+
extra_rdoc_files: []
|
139
|
+
files:
|
140
|
+
- ".gitignore"
|
141
|
+
- ".pullreview.yml"
|
142
|
+
- ".rspec"
|
143
|
+
- ".rubocop.yml"
|
144
|
+
- ".travis.yml"
|
145
|
+
- ".versions.conf"
|
146
|
+
- Gemfile
|
147
|
+
- LICENSE.txt
|
148
|
+
- README.md
|
149
|
+
- Rakefile
|
150
|
+
- bin/netsoul-ruby
|
151
|
+
- ext/netsoul_kerberos/extconf.rb
|
152
|
+
- ext/netsoul_kerberos/kerberos.c
|
153
|
+
- ext/netsoul_kerberos/kerberos.h
|
154
|
+
- ext/netsoul_kerberos/netsoul_kerberos.c
|
155
|
+
- lib/netsoul.rb
|
156
|
+
- lib/netsoul/config.rb
|
157
|
+
- lib/netsoul/errors.rb
|
158
|
+
- lib/netsoul/location.rb
|
159
|
+
- lib/netsoul/logging.rb
|
160
|
+
- lib/netsoul/message.rb
|
161
|
+
- lib/netsoul/version.rb
|
162
|
+
- netsoul.gemspec
|
163
|
+
homepage: https://github.com/fenicks/netsoul-ruby
|
164
|
+
licenses:
|
165
|
+
- MIT
|
166
|
+
metadata: {}
|
167
|
+
post_install_message:
|
168
|
+
rdoc_options: []
|
169
|
+
require_paths:
|
170
|
+
- lib
|
171
|
+
- ext
|
172
|
+
- bin
|
173
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
174
|
+
requirements:
|
175
|
+
- - ">="
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: '0'
|
178
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
179
|
+
requirements:
|
180
|
+
- - ">="
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: '0'
|
183
|
+
requirements: []
|
184
|
+
rubyforge_project:
|
185
|
+
rubygems_version: 2.4.8
|
186
|
+
signing_key:
|
187
|
+
specification_version: 4
|
188
|
+
summary: Netsoul client and library for ruby.
|
189
|
+
test_files: []
|
190
|
+
has_rdoc:
|