Ruby GTK3移行後のメインリポジトリ
Revisão | 6ab5f79002a966254035c953c1458f5a0e90846c (tree) |
---|---|
Hora | 2015-01-24 19:54:12 |
Autor | Shyouzou Sugitani <shy@user...> |
Commiter | Shyouzou Sugitani |
add sstplib.rb
@@ -0,0 +1,202 @@ | ||
1 | +# -*- coding: utf-8 -*- | |
2 | +# | |
3 | +# sstplib.rb - an SSTP library module in Ruby | |
4 | +# Copyright (C) 2001, 2002 by Tamito KAJIYAMA | |
5 | +# Copyright (C) 2002, 2003 by MATSUMURA Namihiko <nie@counterghost.net> | |
6 | +# Copyright (C) 2002-2015 by Shyouzou Sugitani <shy@users.sourceforge.jp> | |
7 | +# | |
8 | +# This program is free software; you can redistribute it and/or modify it | |
9 | +# under the terms of the GNU General Public License (version 2) as | |
10 | +# published by the Free Software Foundation. It is distributed in the | |
11 | +# hope that it will be useful, but WITHOUT ANY WARRANTY; without even the | |
12 | +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |
13 | +# PURPOSE. See the GNU General Public License for more details. | |
14 | +# | |
15 | + | |
16 | +require "socket" | |
17 | + | |
18 | +module SSTPLib | |
19 | + | |
20 | + class SSTPServer < TCPServer | |
21 | + | |
22 | + def initialize(hostname="", port) | |
23 | + super(hostname, port) | |
24 | + #allow_reuse_address = True | |
25 | + setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true) | |
26 | + end | |
27 | + end | |
28 | + | |
29 | + class AsynchronousSSTPServer < SSTPServer | |
30 | + | |
31 | + def handle_request | |
32 | + r, w, e = select.select([self.socket], [], [], 0) | |
33 | + if not r | |
34 | + return | |
35 | + end | |
36 | + SSTPServer.handle_request(self) | |
37 | + end | |
38 | + end | |
39 | + | |
40 | + class BaseSSTPRequestHandler | |
41 | + | |
42 | + RESPONSES = { | |
43 | + 200 => 'OK', | |
44 | + 204 => 'No Content', | |
45 | + 210 => 'Break', | |
46 | + 400 => 'Bad Request', | |
47 | + 408 => 'Request Timeout', | |
48 | + 409 => 'Conflict', | |
49 | + 420 => 'Refuse', | |
50 | + 501 => 'Not Implemented', | |
51 | + 503 => 'Service Unavailable', | |
52 | + 510 => 'Not Local IP', | |
53 | + 511 => 'In Black List', | |
54 | + 512 => 'Invisible', | |
55 | + } | |
56 | + | |
57 | + def initialize(fp) | |
58 | + @fp = fp | |
59 | + end | |
60 | + | |
61 | + def parse_headers() | |
62 | + if @fp == nil | |
63 | + return | |
64 | + end | |
65 | + headers = [] | |
66 | + while true | |
67 | + line = @fp.readline() | |
68 | + if line.strip.empty? | |
69 | + break | |
70 | + end | |
71 | + if line.end_with?("\r\n") | |
72 | + line = line[0..-3] | |
73 | + elsif line.end_with?("\n") | |
74 | + line = line[0..-2] | |
75 | + end | |
76 | + headers << line | |
77 | + end | |
78 | + message = {} | |
79 | + for h in headers | |
80 | + if h.include?(":") | |
81 | + key, value = h.split(":", 2) | |
82 | + message[key] = value.strip | |
83 | + end | |
84 | + end | |
85 | + if message.keys.include?("Charset") | |
86 | + charset = message["Charset"] | |
87 | + else | |
88 | + charset = "Shift_JIS" | |
89 | + end | |
90 | + for key in message.keys | |
91 | + message[key] = message[key].force_encoding(charset).encode("UTF-8", :invalid => :replace) | |
92 | + end | |
93 | + return message | |
94 | + end | |
95 | + | |
96 | + def parse_request(requestline) | |
97 | + requestline = requestline.encode('Shift_JIS') | |
98 | + if requestline.end_with?("\r\n") | |
99 | + requestline = requestline[0..-3] | |
100 | + elsif requestline.end_with?("\n") | |
101 | + requestline = requestline[0..-2] | |
102 | + end | |
103 | + @requestline = requestline | |
104 | + re_requestsyntax = Regexp.new('^([A-Z]+) SSTP/([0-9]\\.[0-9])$') | |
105 | + match = re_requestsyntax.match(requestline) | |
106 | + if not match | |
107 | + @equestline = '-' | |
108 | + send_error(400, 'Bad Request ' + requestline.to_s) | |
109 | + return 0 | |
110 | + end | |
111 | + @command, @version = match[1, 2] | |
112 | + @headers = parse_headers() | |
113 | + return 1 | |
114 | + end | |
115 | + | |
116 | + def handle(line) | |
117 | + @error = @version = nil | |
118 | + if not parse_request(line) | |
119 | + return | |
120 | + end | |
121 | + name = "do_" + @command.to_s + "_" + @version[0] + "_" + @version[2] | |
122 | + begin | |
123 | + method(name).call() | |
124 | + rescue | |
125 | + send_error( | |
126 | + 501, | |
127 | + 'Not Implemented (' + @command + '/' + @version + ')') | |
128 | + return | |
129 | + end | |
130 | + end | |
131 | + | |
132 | + def send_error(code, message=nil) | |
133 | + @error = code | |
134 | + log_error((message or RESPONSES[code])) | |
135 | + send_response(code, RESPONSES[code]) | |
136 | + end | |
137 | + | |
138 | + def send_response(code, message=nil) | |
139 | + log_request(code, message) | |
140 | + @fp.write("SSTP/" + (@version or "1.0") + " " + code.to_i.to_s + " " + RESPONSES[code] + "\r\n\r\n") | |
141 | + end | |
142 | + | |
143 | + def log_error(message) | |
144 | +# logging.error('[{0}] {1}\n'.format(self.timestamp(), message)) | |
145 | + end | |
146 | + | |
147 | + def log_request(code, message=None) | |
148 | + if @requestline == '-' | |
149 | + request = @requestline | |
150 | + else | |
151 | + request = ['"', @requestline, '"'].join("") | |
152 | + end | |
153 | +# logging.info('{0} [{1}] {2} {3:d} {4}\n'.format( | |
154 | +# self.client_hostname(), self.timestamp(), | |
155 | +# request, code, (message or RESPONSES[code]))) | |
156 | + end | |
157 | + | |
158 | + def client_hostname | |
159 | + begin | |
160 | + host, port = self.client_address | |
161 | + rescue #except: | |
162 | + return 'localhost' | |
163 | + end | |
164 | + begin | |
165 | + hostname, aliaslist, ipaddrlist = socket.gethostbyaddr(host) | |
166 | + rescue #except socket.error: | |
167 | + hostname = host | |
168 | + end | |
169 | + return hostname | |
170 | + end | |
171 | + | |
172 | + def timestamp | |
173 | + month_names = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', | |
174 | + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] | |
175 | + t = Time.now.localtime | |
176 | + m = month_names[t.month - 1] | |
177 | + ## FIXME ## | |
178 | + return t'{0:02d}/{1}/{2:d}:{3:02d}:{4:02d}:{5:02d} {6:+05d}'.format( | |
179 | + t[2], m, t[0], t[3], t[4], t[5], (-time.timezone / 36).to_i) | |
180 | + end | |
181 | + end | |
182 | + | |
183 | + | |
184 | + class TEST | |
185 | + | |
186 | + def initialize(port = 9801) | |
187 | + sstpd = SSTPServer.new('', port) | |
188 | + print('Serving SSTP on port ' + port.to_i.to_s + ' ...' + "\n") | |
189 | + opt = sstpd.getsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR) | |
190 | + print('Allow reuse address: ' + opt.int.to_s + "\n") | |
191 | + while true | |
192 | + s = sstpd.accept | |
193 | + handler = BaseSSTPRequestHandler.new(s) | |
194 | + buffer = s.gets | |
195 | + handler.handle(buffer) | |
196 | + s.close | |
197 | + end | |
198 | + end | |
199 | + end | |
200 | +end | |
201 | + | |
202 | +SSTPLib::TEST.new |