rstyx 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +63 -0
- data/History.txt +8 -0
- data/Manifest.txt +0 -1
- data/Rakefile +17 -15
- data/examples/fileondisk.rb +32 -3
- data/examples/readstyxfile.rb +16 -19
- data/examples/testserver.rb +32 -3
- data/examples/writestyxfile.rb +16 -19
- data/lib/rstyx/client.rb +16 -71
- data/lib/rstyx/common.rb +15 -18
- data/lib/rstyx/errors.rb +16 -19
- data/lib/rstyx/keyring.rb +79 -23
- data/lib/rstyx/messages.rb +16 -19
- data/lib/rstyx/server.rb +268 -66
- data/lib/rstyx/version.rb +17 -16
- data/lib/rstyx.rb +17 -15
- data/tests/tc_client.rb +16 -15
- data/tests/tc_message.rb +17 -15
- data/tests/tc_styxservproto.rb +16 -15
- metadata +2 -3
- data/lib/rstyx/authmodules.rb +0 -90
data/lib/rstyx/server.rb
CHANGED
@@ -1,42 +1,40 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
2
|
#
|
3
|
+
# Author:: Rafael R. Sevilla (mailto:dido@imperium.ph)
|
4
|
+
# Copyright:: Copyright (c) 2005-2007 Rafael R. Sevilla
|
5
|
+
# Homepage:: http://rstyx.rubyforge.org/
|
6
|
+
# License:: GNU Lesser General Public License / Ruby License
|
7
|
+
#
|
8
|
+
# $Id: server.rb 278 2007-09-19 07:22:37Z dido $
|
9
|
+
#
|
10
|
+
#----------------------------------------------------------------------------
|
11
|
+
#
|
3
12
|
# Copyright (C) 2005-2007 Rafael Sevilla
|
4
13
|
# This file is part of RStyx
|
5
14
|
#
|
6
|
-
#
|
7
|
-
# it under the terms of the GNU Lesser General Public License
|
8
|
-
# published by the Free Software Foundation; either version
|
9
|
-
#
|
15
|
+
# This program is free software; you can redistribute it and/or modify
|
16
|
+
# it under the terms of either 1) the GNU Lesser General Public License
|
17
|
+
# as published by the Free Software Foundation; either version 3 of the
|
18
|
+
# License, or (at your option) any later version; or 2) Ruby's license.
|
10
19
|
#
|
11
|
-
#
|
12
|
-
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
-
# MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
-
# GNU Lesser General Public License for more details.
|
20
|
+
# See the file COPYING for complete licensing information
|
15
21
|
#
|
16
|
-
|
17
|
-
# License along with RStyx; if not, write to the Free Software
|
18
|
-
# Foundation, Inc., 51 Franklin St., Fifth Floor, Boston, MA
|
19
|
-
# 02110-1301 USA.
|
22
|
+
#----------------------------------------------------------------------------
|
20
23
|
#
|
21
24
|
# Styx Server
|
22
25
|
#
|
23
26
|
# To create a Styx server, one has to create an SDirectory object that
|
24
27
|
# acts as the server root, e.g.:
|
25
28
|
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
29
|
+
# sd = RStyx::Server::SDirectory.new("/")
|
30
|
+
# sf = RStyx::Server::InMemoryFile.new("test.file")
|
31
|
+
# sf.contents = "hello"
|
32
|
+
# sd << sf
|
33
|
+
# serv = RStyx::Server::TCPServer.new(:bindaddr => "0.0.0.0",
|
34
|
+
# :port => 9876,
|
35
|
+
# :root => sd)
|
36
|
+
# serv.run.join
|
34
37
|
#
|
35
|
-
# Author:: Rafael R. Sevilla (mailto:dido@imperium.ph)
|
36
|
-
# Copyright:: Copyright (c) 2005-2007 Rafael R. Sevilla
|
37
|
-
# License:: GNU Lesser General Public License
|
38
|
-
#
|
39
|
-
# $Id: server.rb 249 2007-09-14 04:21:18Z dido $
|
40
38
|
#
|
41
39
|
require 'thread'
|
42
40
|
require 'monitor'
|
@@ -59,7 +57,31 @@ module RStyx
|
|
59
57
|
# assemble all inbound messages
|
60
58
|
#
|
61
59
|
module StyxServerProtocol
|
62
|
-
|
60
|
+
##
|
61
|
+
# maximum message size supported
|
62
|
+
attr_accessor :msize
|
63
|
+
##
|
64
|
+
# Logger object used for logging server events
|
65
|
+
attr_accessor :log
|
66
|
+
##
|
67
|
+
# The root of the file tree for this server
|
68
|
+
attr_accessor :root
|
69
|
+
##
|
70
|
+
# An authenticator which is sent messages received from the client.
|
71
|
+
# Used when doing Inferno authentication.
|
72
|
+
attr_accessor :authenticator
|
73
|
+
##
|
74
|
+
# The session object corresponding to this connection
|
75
|
+
attr_accessor :session
|
76
|
+
##
|
77
|
+
# Server's authentication information
|
78
|
+
attr_accessor :myauth
|
79
|
+
##
|
80
|
+
# Connected peer's authentication information
|
81
|
+
attr_accessor :userauth
|
82
|
+
##
|
83
|
+
# Shared secret obtained during Inferno authentication
|
84
|
+
attr_accessor :secret
|
63
85
|
|
64
86
|
DEFAULT_MSIZE = 8216
|
65
87
|
|
@@ -95,11 +117,11 @@ module RStyx
|
|
95
117
|
# negotiation results in the protocol_negotiated flag in the
|
96
118
|
# current session becoming true, and all other outstanding I/O
|
97
119
|
# on the session (e.g. opened fids and the like) all removed.
|
98
|
-
|
120
|
+
#--
|
99
121
|
# External methods used:
|
100
122
|
#
|
101
123
|
# Session#reset_session *
|
102
|
-
|
124
|
+
#++
|
103
125
|
def tversion(msg)
|
104
126
|
@cversion = msg.version
|
105
127
|
@cmsize = msg.msize
|
@@ -123,7 +145,7 @@ module RStyx
|
|
123
145
|
# depending on the auth methods that we decide to support.
|
124
146
|
#
|
125
147
|
def tauth(msg)
|
126
|
-
return(Message::Rerror.new(:ename => "Authentication methods through auth messages are not
|
148
|
+
return(Message::Rerror.new(:ename => "Authentication methods through auth messages are not supported."))
|
127
149
|
end
|
128
150
|
|
129
151
|
##
|
@@ -134,14 +156,14 @@ module RStyx
|
|
134
156
|
# 1. The client has not done a version negotiation yet.
|
135
157
|
# 2. The client has provided a fid which it is already using
|
136
158
|
# for something else.
|
137
|
-
|
159
|
+
#--
|
138
160
|
# External methods used:
|
139
161
|
#
|
140
162
|
# Session#version_negotiated? *
|
141
163
|
# Session#has_fid? *
|
142
164
|
# Session#[]= *
|
143
165
|
# SFile#qid (root) *
|
144
|
-
|
166
|
+
#++
|
145
167
|
def tattach(msg)
|
146
168
|
# Do not allow attaches without version negotiation
|
147
169
|
unless @session.version_negotiated?
|
@@ -175,11 +197,11 @@ module RStyx
|
|
175
197
|
# flushed transaction). Some means, possibly a session-wide
|
176
198
|
# global transaction lock on server internal state changes
|
177
199
|
# may be necessary to allow flushes of this kind to work.
|
178
|
-
|
200
|
+
#--
|
179
201
|
# External methods used:
|
180
202
|
#
|
181
203
|
# Session#flush_tag *
|
182
|
-
|
204
|
+
#++
|
183
205
|
def tflush(msg)
|
184
206
|
@session.flush_tag(msg.oldtag)
|
185
207
|
return(Message::Rflush.new)
|
@@ -205,7 +227,7 @@ module RStyx
|
|
205
227
|
# Note that if several parts of the walk managed to succeed, this
|
206
228
|
# method will still return an Rwalk response, but it will NOT
|
207
229
|
# associate newfid with anything.
|
208
|
-
|
230
|
+
#--
|
209
231
|
# External methods used:
|
210
232
|
#
|
211
233
|
# Session#[] *
|
@@ -218,7 +240,7 @@ module RStyx
|
|
218
240
|
# SFile#atime=
|
219
241
|
# SFile#[]
|
220
242
|
# SFile#qid
|
221
|
-
|
243
|
+
#++
|
222
244
|
#
|
223
245
|
def twalk(msg)
|
224
246
|
if msg.wnames.length > MAXWELEM
|
@@ -232,13 +254,12 @@ module RStyx
|
|
232
254
|
raise StyxException.new("cannot walk to an open fid")
|
233
255
|
end
|
234
256
|
nfid = msg.newfid
|
235
|
-
if
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
raise StyxException.new("fid already in use")
|
240
|
-
end
|
257
|
+
# if the original and new fids are different, check that
|
258
|
+
# the new fid isn't already in use.
|
259
|
+
if nfid != fid && @session.has_fid?(nfid)
|
260
|
+
raise StyxException.new("fid already in use")
|
241
261
|
end
|
262
|
+
|
242
263
|
rwalk = Message::Rwalk.new(:qids => [])
|
243
264
|
num = 0
|
244
265
|
msg.wnames.each do |n|
|
@@ -258,6 +279,7 @@ module RStyx
|
|
258
279
|
end
|
259
280
|
break
|
260
281
|
end
|
282
|
+
sf.atime = Time.now
|
261
283
|
# This allows a client to get a fid representing the directory
|
262
284
|
# at the end of the walk, even if the client does not have
|
263
285
|
# execute permissions on that directory. Therefore, in Inferno,
|
@@ -279,7 +301,7 @@ module RStyx
|
|
279
301
|
|
280
302
|
##
|
281
303
|
# Handle open messages.
|
282
|
-
|
304
|
+
#--
|
283
305
|
# External methods used:
|
284
306
|
#
|
285
307
|
# Session#[]
|
@@ -289,7 +311,7 @@ module RStyx
|
|
289
311
|
# SFile#qid
|
290
312
|
# Session#iounit
|
291
313
|
# Session#user
|
292
|
-
|
314
|
+
#++
|
293
315
|
def topen(msg)
|
294
316
|
sf = @session[msg.fid]
|
295
317
|
mode = msg.mode
|
@@ -312,11 +334,38 @@ module RStyx
|
|
312
334
|
unless @session.writable?(dir)
|
313
335
|
raise StyxException.new("permission denied, no write permissions to parent directory")
|
314
336
|
end
|
337
|
+
# Check the file type
|
338
|
+
perm = msg.perm
|
339
|
+
isdir = (perm & DMDIR) != 0
|
340
|
+
isapponly = (perm & DMAPPEND) != 0
|
341
|
+
isexclusive = (perm & DMEXCL) != 0
|
342
|
+
isauth = (perm & DMAUTH) != 0
|
343
|
+
|
344
|
+
if isauth
|
345
|
+
# Auth files cannot be created by Styx messages
|
346
|
+
raise StyxException.new("can't create a file of type DMAUTH")
|
347
|
+
end
|
348
|
+
|
349
|
+
# Get the low 9 bits of the permission number (these low 9 bits
|
350
|
+
# are the rwxrwxrwx file permissions)
|
351
|
+
operm = msg.perm & 01777
|
352
|
+
# Get the real permissions of this file. This depends on the
|
353
|
+
# permissions of the parent directory
|
354
|
+
realperm = operm
|
355
|
+
if isdir
|
356
|
+
realperm = operm & (~0777 | (dir.permissions & 0777))
|
357
|
+
# directories must be opened with OREAD (no other bits set)
|
358
|
+
if msg.mode != OREAD
|
359
|
+
raise StyxException.new("when creating a directory must open with read permission only")
|
360
|
+
end
|
361
|
+
else
|
362
|
+
realperm = operm & (~0666 | (dir.permissions & 0666))
|
363
|
+
end
|
315
364
|
|
316
|
-
# Create the file in the directory
|
317
|
-
#
|
318
|
-
new_file = dir.newfile(msg.name,
|
319
|
-
|
365
|
+
# Create the file in the directory, add it to the directory tree,
|
366
|
+
# and associate the new file with the given fid
|
367
|
+
new_file = dir.newfile(msg.name, realperm, isdir, isapponly, isexcl)
|
368
|
+
dir << new_file
|
320
369
|
@session[msg.fid] = new_file
|
321
370
|
new_file.add_client(SFileClient.new(@session, msg.fid, msg.mode))
|
322
371
|
return(Message::Rcreate.new(:qid => new_file.qid,
|
@@ -383,7 +432,7 @@ o dir << new_file
|
|
383
432
|
# A remove is just like a clunk with the side effect of
|
384
433
|
# removing the file if the permissions allow.
|
385
434
|
sf = @session[msg.fid]
|
386
|
-
sf.
|
435
|
+
sf.synchronize do
|
387
436
|
@session.clunk(msg.fid)
|
388
437
|
parent = sf.parent
|
389
438
|
if @session.writable?(parent)
|
@@ -394,8 +443,8 @@ o dir << new_file
|
|
394
443
|
raise StyxException.new("directory not empty")
|
395
444
|
end
|
396
445
|
sf.remove
|
446
|
+
parent.set_mtime(Time.now, @session.user)
|
397
447
|
end
|
398
|
-
parent.set_mtime(Time.now, @session.user)
|
399
448
|
return(Message::Rremove.new)
|
400
449
|
end
|
401
450
|
|
@@ -414,7 +463,7 @@ o dir << new_file
|
|
414
463
|
def twstat(msg)
|
415
464
|
nstat = msg.stat
|
416
465
|
sf = @session[msg.fid]
|
417
|
-
sf.
|
466
|
+
sf.synchronize do
|
418
467
|
# Check if we are changing the file's name
|
419
468
|
unless nstat.name.empty?
|
420
469
|
dir = sf.parent
|
@@ -554,8 +603,10 @@ o dir << new_file
|
|
554
603
|
@log.error("#{@peername} unknown fid in message #{msg.to_s}")
|
555
604
|
reply(Message::Rerror.new(:ename => "Unknown fid #{e.fid}"), tag)
|
556
605
|
rescue StyxException => e
|
557
|
-
@log.error("#{@peername} styx exception #{e.message}
|
606
|
+
@log.error("#{@peername} styx exception #{e.message} for #{msg.to_s}")
|
558
607
|
reply(Message::Rerror.new(:ename => "Error: #{e.message}"), tag)
|
608
|
+
rescue Exception => e
|
609
|
+
@log.error("#{@peername} internal error #{e.message} for #{e.to_s} at #{e.backtrace}")
|
559
610
|
end
|
560
611
|
|
561
612
|
end
|
@@ -565,6 +616,12 @@ o dir << new_file
|
|
565
616
|
# Receive data from the network connection, called by EventMachine.
|
566
617
|
#
|
567
618
|
def receive_data(data)
|
619
|
+
# If we are in keyring authentication mode, write any data received
|
620
|
+
# into the @auth's buffer, and simply return.
|
621
|
+
unless @authenticator.nil?
|
622
|
+
@authenticator << data
|
623
|
+
return
|
624
|
+
end
|
568
625
|
@msgbuffer << data
|
569
626
|
# self.class.log.debug(" << #{data.unpack("H*").inspect}")
|
570
627
|
while @msgbuffer.length > 4
|
@@ -621,6 +678,10 @@ o dir << new_file
|
|
621
678
|
# Active iounit for this connection
|
622
679
|
#
|
623
680
|
attr_accessor :iounit
|
681
|
+
##
|
682
|
+
# Group table
|
683
|
+
#
|
684
|
+
attr_accessor :groups
|
624
685
|
|
625
686
|
##
|
626
687
|
# Create a new session.
|
@@ -772,15 +833,17 @@ o dir << new_file
|
|
772
833
|
end
|
773
834
|
end
|
774
835
|
|
836
|
+
# These constants are used by Session#permission? and should NOT
|
837
|
+
# be changed. The algorithm used depends on it!
|
838
|
+
EXECUTE = 0
|
839
|
+
WRITE = 1
|
840
|
+
READ = 2
|
841
|
+
|
775
842
|
##
|
776
843
|
# Check the permissions for a given mode
|
777
844
|
#
|
778
|
-
#--
|
779
|
-
# FIXME: the permissions are only for anonymous access at the
|
780
|
-
# moment, so only the world permissions are ever checked.
|
781
|
-
#++
|
782
845
|
# _sf_:: the file to check against
|
783
|
-
# _mode_:: the mode to check (
|
846
|
+
# _mode_:: the mode to check (EXEC, WRITE, or READ)
|
784
847
|
#
|
785
848
|
def permission?(sf, mode)
|
786
849
|
if mode < 0 || mode > 2
|
@@ -788,22 +851,42 @@ o dir << new_file
|
|
788
851
|
end
|
789
852
|
# We bit shift the permissions value so that the mode is
|
790
853
|
# represented by the last bit (all) the fourth to last bit
|
791
|
-
# (group), and the seventh-to-last bit (user).
|
854
|
+
# (group), and the seventh-to-last bit (user). For example,
|
855
|
+
# if we started with a mode of 0755 (binary 111101101,
|
856
|
+
# rwxrwxrwx), and we want to check write permissions, we
|
857
|
+
# shift by one bit so that the value of perms is 1110110, or
|
858
|
+
# (rwxrwxrw).
|
792
859
|
perms = sf.permissions >> mode
|
793
860
|
# Check permissions for 'all' -- the low-order bit
|
794
|
-
|
861
|
+
unless perms & 0b000_000_001 == 0
|
795
862
|
return(true)
|
796
863
|
end
|
797
864
|
|
798
|
-
#
|
799
|
-
|
865
|
+
# Group permissions
|
866
|
+
unless (perms & 0b000_001_000) == 0
|
867
|
+
# The group has the correct permissions; now we have to find if
|
868
|
+
# the user is a member of the group in question.
|
869
|
+
ug = @groups[@user]
|
870
|
+
unless ug.index(sf.gid).nil?
|
871
|
+
return(true)
|
872
|
+
end
|
873
|
+
end
|
874
|
+
|
875
|
+
# Owner permissions. This is the final fallback.
|
876
|
+
return(((perms & 0b001_000_000) != 0) && (@user == sf.uid))
|
800
877
|
end
|
801
878
|
|
802
879
|
##
|
803
880
|
# Check for executable permission for the SFile _sf_.
|
804
881
|
#
|
805
882
|
def execute?(sf)
|
806
|
-
return(
|
883
|
+
return(permission?(sf, EXECUTE))
|
884
|
+
end
|
885
|
+
|
886
|
+
##
|
887
|
+
# Check for write permission for the SFile _sf_.
|
888
|
+
def writable?(sf)
|
889
|
+
return(permission?(sf, WRITE))
|
807
890
|
end
|
808
891
|
|
809
892
|
##
|
@@ -818,7 +901,59 @@ o dir << new_file
|
|
818
901
|
raise StyxException.new("can't open locked file")
|
819
902
|
end
|
820
903
|
openmode = mode & 0x03
|
821
|
-
|
904
|
+
case openmode
|
905
|
+
when OREAD
|
906
|
+
unless permission?(sf, READ)
|
907
|
+
raise StyxException.new("read permission denied")
|
908
|
+
end
|
909
|
+
when OWRITE
|
910
|
+
unless permission?(sf, WRITE)
|
911
|
+
raise StyxException.new("write permission denied")
|
912
|
+
end
|
913
|
+
when ORDWR
|
914
|
+
unless permission?(sf, READ)
|
915
|
+
raise StyxException.new("read permission denied")
|
916
|
+
end
|
917
|
+
unless permission?(sf, WRITE)
|
918
|
+
raise StyxException.new("write permission denied")
|
919
|
+
end
|
920
|
+
when OEXEC
|
921
|
+
unless permission?(sf, EXECUTE)
|
922
|
+
raise StyxException.new("execute permission denied")
|
923
|
+
end
|
924
|
+
else
|
925
|
+
# shouldn't happen
|
926
|
+
raise StyxException.new("internal Styx error openmode = #{openmode}: should be between 0 and 3")
|
927
|
+
end
|
928
|
+
|
929
|
+
# Execute permission is required for a directory in order to
|
930
|
+
# do anything with it
|
931
|
+
if sf.directory? && !execute?(sf)
|
932
|
+
raise StyxException("directory execute permission denied")
|
933
|
+
end
|
934
|
+
|
935
|
+
if (mode & OTRUNC) != 0
|
936
|
+
# can't truncate a directory
|
937
|
+
if sf.directory?
|
938
|
+
raise StyxException.new("cannot truncate a directory")
|
939
|
+
end
|
940
|
+
unless permission?(sf, WRITE)
|
941
|
+
raise StyxException.new("need write permissions to truncate a file")
|
942
|
+
end
|
943
|
+
end
|
944
|
+
|
945
|
+
if (mode & ORCLOSE) != 0
|
946
|
+
# can't delete a directory on closing
|
947
|
+
if sf.directory?
|
948
|
+
raise StyxException.new("cannot automatically delete a directory")
|
949
|
+
end
|
950
|
+
# we must have write permissions on the parent directory and the file
|
951
|
+
# itself to delete the file on clunking its fid
|
952
|
+
unless permission?(sf.parent, WRITE)
|
953
|
+
raise StyxException.new("need write permissions on the parent directory to delete the file when the fid is clunked")
|
954
|
+
end
|
955
|
+
# TODO: do we need write permissions on the file itself?
|
956
|
+
end
|
822
957
|
end
|
823
958
|
|
824
959
|
end # class Session
|
@@ -837,12 +972,27 @@ o dir << new_file
|
|
837
972
|
# serve (typically an SDirectory instance)
|
838
973
|
# _:log_:: A Logger object where server-generated log messages
|
839
974
|
# are stored.
|
975
|
+
# _:auth_:: An authentication object. If this is a
|
976
|
+
# Keyring::Authinfo instance, it will use the Inferno
|
977
|
+
# authentication protocol to authenticate clients who
|
978
|
+
# connect, and only allow connections from clients with
|
979
|
+
# certificates signed by the same CA that signed its
|
980
|
+
# own certificate. If this is nil, no authentication
|
981
|
+
# will be required for connections.
|
982
|
+
# _:groups_:: A hash table, indexed by user names, that returns
|
983
|
+
# an array of groups of which a particular user is
|
984
|
+
# member of. If not specified, it defaults to an
|
985
|
+
# empty group table (which sets the group of everyone
|
986
|
+
# to 'nogroup')
|
840
987
|
# _:debug_:: Debug level, which is assigned to the logger's level
|
841
988
|
# Set this to Logger::DEBUG if you want full debugging
|
842
989
|
# messages to appear.
|
843
990
|
#
|
844
991
|
def initialize(config)
|
845
992
|
@root = config[:root]
|
993
|
+
@auth = config[:auth]
|
994
|
+
@groups = config[:groups]
|
995
|
+
@groups ||= Hash.new(["nogroup"])
|
846
996
|
@log = config[:log] || Logger.new(STDERR)
|
847
997
|
@log.level = config[:debug] || Logger::WARN
|
848
998
|
end
|
@@ -898,6 +1048,51 @@ o dir << new_file
|
|
898
1048
|
StyxServerProtocol) do |conn|
|
899
1049
|
conn.root = @root
|
900
1050
|
conn.log = @log
|
1051
|
+
if @auth.is_a?(Keyring::Authinfo)
|
1052
|
+
# Perform Inferno authentication protocol
|
1053
|
+
conn.myauth = @auth
|
1054
|
+
conn.authenticator = Keyring::FileWrapper.new(conn)
|
1055
|
+
Thread.new do
|
1056
|
+
begin
|
1057
|
+
conn.userauth, conn.secret = Keyring.auth(conn.authenticator,
|
1058
|
+
:server, @auth,
|
1059
|
+
["none"])
|
1060
|
+
rescue Exception => e
|
1061
|
+
# You fail. Get outta my face!
|
1062
|
+
@log.info("client authentication error #{e.class.to_s}: #{e.message}")
|
1063
|
+
conn.close_connection
|
1064
|
+
else
|
1065
|
+
# Successful authentication. Set the session.auth flag to
|
1066
|
+
# true and the user to the owner of the public key that
|
1067
|
+
# was used to authenticate
|
1068
|
+
conn.session.user = conn.userauth.mypk.owner
|
1069
|
+
conn.session.auth = true
|
1070
|
+
@log.info("authenticated connection for #{conn.session.user}")
|
1071
|
+
# Stop using the authenticator after the protocol is done.
|
1072
|
+
# The authenticator might have received some data meant
|
1073
|
+
# to be Styx protocol messages so we do receive_data to
|
1074
|
+
# make sure that the data does get received.
|
1075
|
+
a = conn.authenticator
|
1076
|
+
conn.authenticator = nil
|
1077
|
+
if a.data.length > 0
|
1078
|
+
conn.receive_data(a.data)
|
1079
|
+
end
|
1080
|
+
end
|
1081
|
+
end
|
1082
|
+
else
|
1083
|
+
# Either we're using some other non-Inferno authentication
|
1084
|
+
# method, in which case auth files are used and the peer
|
1085
|
+
# authentication information is filled in later, or we're
|
1086
|
+
# not bothering to do any authentication. We fill in
|
1087
|
+
# userauth with nil (the connection is unauthenticated)
|
1088
|
+
# and we put "nobody" in the username (the anonymous user).
|
1089
|
+
conn.userauth = nil
|
1090
|
+
conn.session.user = "nobody"
|
1091
|
+
conn.session.auth = false
|
1092
|
+
conn.authenticator = nil
|
1093
|
+
@log.info("unauthenticated connection for #{conn.username}")
|
1094
|
+
end
|
1095
|
+
conn.session.groups = @groups
|
901
1096
|
end
|
902
1097
|
end
|
903
1098
|
end
|
@@ -969,7 +1164,7 @@ o dir << new_file
|
|
969
1164
|
# opened it with read access mode).
|
970
1165
|
#
|
971
1166
|
def readable?
|
972
|
-
return(mode == OREAD || mode == ORDWR)
|
1167
|
+
return(@mode == OREAD || @mode == ORDWR)
|
973
1168
|
end
|
974
1169
|
|
975
1170
|
##
|
@@ -977,7 +1172,7 @@ o dir << new_file
|
|
977
1172
|
# opened it with write access).
|
978
1173
|
#
|
979
1174
|
def writable?
|
980
|
-
return(mode == OWRITE || mode == ORDWR)
|
1175
|
+
return(@mode == OWRITE || @mode == ORDWR)
|
981
1176
|
end
|
982
1177
|
|
983
1178
|
end
|
@@ -1473,7 +1668,7 @@ o dir << new_file
|
|
1473
1668
|
# implementation does nothing; subclasses must override this to
|
1474
1669
|
# provide the correct functionality.
|
1475
1670
|
#
|
1476
|
-
def refresh
|
1671
|
+
def refresh(update_children)
|
1477
1672
|
end
|
1478
1673
|
end # class SFile
|
1479
1674
|
|
@@ -1608,10 +1803,17 @@ o dir << new_file
|
|
1608
1803
|
# FIXME: make this method actually DO something!
|
1609
1804
|
#++
|
1610
1805
|
#
|
1611
|
-
def newfile(name, perm)
|
1806
|
+
def newfile(name, perm, isdir, isapponly, isexcl)
|
1612
1807
|
raise StyxException.new("cannot create files in this directory")
|
1613
1808
|
end
|
1614
1809
|
|
1810
|
+
##
|
1811
|
+
# Remove a file from the directory
|
1812
|
+
def remove_child(child)
|
1813
|
+
@children.delete(child)
|
1814
|
+
self.contents_changed
|
1815
|
+
end
|
1816
|
+
|
1615
1817
|
end # class SDirectory
|
1616
1818
|
|
1617
1819
|
##
|
data/lib/rstyx/version.rb
CHANGED
@@ -1,34 +1,35 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
2
|
#
|
3
|
-
#
|
3
|
+
# Author:: Rafael R. Sevilla (mailto:dido@imperium.ph)
|
4
|
+
# Copyright:: Copyright (c) 2005-2007 Rafael R. Sevilla
|
5
|
+
# Homepage:: http://rstyx.rubyforge.org/
|
6
|
+
# License:: GNU Lesser General Public License / Ruby License
|
7
|
+
#
|
8
|
+
# $Id: version.rb 285 2007-09-19 07:32:56Z dido $
|
9
|
+
#
|
10
|
+
#----------------------------------------------------------------------------
|
11
|
+
#
|
12
|
+
# Copyright (C) 2005-2007 Rafael Sevilla
|
4
13
|
# This file is part of RStyx
|
5
14
|
#
|
6
|
-
#
|
7
|
-
# it under the terms of the GNU Lesser General Public License
|
8
|
-
# published by the Free Software Foundation; either version
|
9
|
-
#
|
15
|
+
# This program is free software; you can redistribute it and/or modify
|
16
|
+
# it under the terms of either 1) the GNU Lesser General Public License
|
17
|
+
# as published by the Free Software Foundation; either version 3 of the
|
18
|
+
# License, or (at your option) any later version; or 2) Ruby's license.
|
10
19
|
#
|
11
|
-
#
|
12
|
-
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
-
# MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
-
# GNU Lesser General Public License for more details.
|
20
|
+
# See the file COPYING for complete licensing information
|
15
21
|
#
|
16
|
-
|
17
|
-
# License along with RStyx; if not, write to the Free Software
|
18
|
-
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
19
|
-
# 02111-1307 USA.
|
22
|
+
#----------------------------------------------------------------------------
|
20
23
|
#
|
21
24
|
# RStyx version code
|
22
25
|
#
|
23
|
-
# $Id: version.rb 261 2007-09-18 04:43:42Z dido $
|
24
|
-
#
|
25
26
|
|
26
27
|
module RStyx
|
27
28
|
module Version
|
28
29
|
|
29
30
|
MAJOR = 0
|
30
31
|
MINOR = 4
|
31
|
-
TINY =
|
32
|
+
TINY = 1
|
32
33
|
|
33
34
|
# The version of RStyx in use.
|
34
35
|
STRING = [ MAJOR, MINOR, TINY ].join(".")
|
data/lib/rstyx.rb
CHANGED
@@ -1,31 +1,33 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
2
|
#
|
3
|
-
#
|
3
|
+
# Author:: Rafael R. Sevilla (mailto:dido@imperium.ph)
|
4
|
+
# Copyright:: Copyright (c) 2005-2007 Rafael R. Sevilla
|
5
|
+
# Homepage:: http://rstyx.rubyforge.org/
|
6
|
+
# License:: GNU Lesser General Public License / Ruby License
|
7
|
+
#
|
8
|
+
# $Id: rstyx.rb 294 2007-09-19 07:45:28Z dido $
|
9
|
+
#
|
10
|
+
#----------------------------------------------------------------------------
|
11
|
+
#
|
12
|
+
# Copyright (C) 2005-2007 Rafael Sevilla
|
4
13
|
# This file is part of RStyx
|
5
14
|
#
|
6
|
-
#
|
7
|
-
# it under the terms of the GNU Lesser General Public License
|
8
|
-
# published by the Free Software Foundation; either version
|
9
|
-
#
|
15
|
+
# This program is free software; you can redistribute it and/or modify
|
16
|
+
# it under the terms of either 1) the GNU Lesser General Public License
|
17
|
+
# as published by the Free Software Foundation; either version 3 of the
|
18
|
+
# License, or (at your option) any later version; or 2) Ruby's license.
|
10
19
|
#
|
11
|
-
#
|
12
|
-
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
-
# MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
-
# GNU Lesser General Public License for more details.
|
20
|
+
# See the file COPYING for complete licensing information
|
15
21
|
#
|
16
|
-
|
17
|
-
# License along with RStyx; if not, write to the Free Software
|
18
|
-
# Foundation, Inc., 51 Franklin St., Fifth Floor, Boston, MA
|
19
|
-
# 02110-1301 USA.
|
22
|
+
#----------------------------------------------------------------------------
|
20
23
|
#
|
21
24
|
# Main require -- should get everything ready for the user of the lib.
|
22
25
|
#
|
23
|
-
# $Id: rstyx.rb 260 2007-09-18 04:43:12Z dido $
|
24
26
|
#
|
25
27
|
require 'rstyx/common'
|
26
28
|
require 'rstyx/messages'
|
27
29
|
require 'rstyx/errors'
|
28
30
|
require 'rstyx/keyring'
|
29
31
|
require 'rstyx/client'
|
30
|
-
require 'rstyx/
|
32
|
+
require 'rstyx/server'
|
31
33
|
|