rstyx 0.4.0 → 0.4.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/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
|
|