aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/sledjchisl/NOTES.txt
diff options
context:
space:
mode:
authoronefang2020-04-19 14:11:16 +1000
committeronefang2020-04-19 14:11:16 +1000
commitb2750deb586644a8052b51b1cf60de731462861c (patch)
tree7500a8f57a821f64dd61e126004c4fd2fa845f5d /src/sledjchisl/NOTES.txt
parentInstall more packages for the new sledjchisl build. (diff)
downloadopensim-SC_OLD-b2750deb586644a8052b51b1cf60de731462861c.zip
opensim-SC_OLD-b2750deb586644a8052b51b1cf60de731462861c.tar.gz
opensim-SC_OLD-b2750deb586644a8052b51b1cf60de731462861c.tar.bz2
opensim-SC_OLD-b2750deb586644a8052b51b1cf60de731462861c.tar.xz
Move NOTES.txt, and write some more.
Diffstat (limited to 'src/sledjchisl/NOTES.txt')
-rw-r--r--src/sledjchisl/NOTES.txt479
1 files changed, 0 insertions, 479 deletions
diff --git a/src/sledjchisl/NOTES.txt b/src/sledjchisl/NOTES.txt
deleted file mode 100644
index e80b8d9..0000000
--- a/src/sledjchisl/NOTES.txt
+++ /dev/null
@@ -1,479 +0,0 @@
1I'm re-purposing this for SledjHamr https://sledjhamr.org/git/docs/index.html
2
3The general structure of SledjHamr is a bunch of servers talking to each
4other via Internet (or just local) connections. One of them is a web
5server for assets, world data, and inventory.
6
7Originally I didn't think using a web based world client was a good idea,
8however it might be better to have one, for reasons. Now I need a web
9management console that can do all the things the current tmux console
10can, including OpenSim console and commands. Plus account management for
11users. I can also use a web based Jabber / XMPP front end to chat, IM,
12and group chatter, which would run in the normal viewers web browser.
13This provides a doorway into putting SledjHamr stuff in existing viewers
14without needing them to support it. So a web based viewer now makes more
15sense, and also means we can get away with not needing a viewer at all.
16
17Toybox itself doesn't include a web server, and I don't think there is
18one on the roadmap. So we have to use an external web server, which was
19a design goal of SledjHamr in the first place, using existing mature
20HTTP infrastructure, coz that's already solved problems for a bunch of
21things that plague OS/SL to this day. Clear your cache! Pffft.
22
23So sledjchisl.c will be the "love world server", though initially it just
24drives OpenSim_SC in tmux via tmux commands to send keys and read output.
25Later it might run opensim_SC directly and use STDIN and STDOUT to do
26everything. It'll also provide the text management front end that runs
27in the left tmux panel of the first window, which is why it's based on
28boxes in the first place. Later still it can take over opensim_SC
29functions as I move them out of mono.
30
31We will need a text, web, and GUI version of this management front end.
32Hmmm, maybe don't need a GUI version, GUI users can just run a terminal.
33
34After much research, FastCGI / FCGI seems to be the most portable way of
35interfacing with existing web servers. FCGI protocol closes STDERR and
36STDOUT, and uses STDIN as it's two way communications channel to the web
37server, so our FCGI module can't be used as the text management front
38end. This is probably a good idea to keep them seperate anyway, for
39security, coz the web server is exposed to the world, the console isn't.
40
41Currently sledjchisl.c tests to see if it's running in tmux already, if
42it isn't it starts up tmux runs itself into this new tmux, then exits.
43So it could also test if it's running from FCGI, and switch to web mode,
44then it'll need to find the tmuxed instance to send commands to it.
45Either via nails connection, or sending tmux commands via shell.
46
47FCGI has methods of dealing with auth and templates. B-)
48
49So for now I think I'll have the text and web management front ends in
50sledjchisl.c, and the love world server as well. I can split them up
51later if I need to.
52
53
54
55
56I has Apache 2.4.25-3+deb9u9
57 MariaDB 10.1.44-MariaDB
58
59
60https://gist.github.com/dermesser/e2f9b66457ae19ebd116
61 Multithreaded example in C.
62
63
64-------------------------------------------------------------------
65
66Apache doesn't seem to support FCGI filter role, so I might have to do
67without. Might be better anyway.
68
69
70"A Filter is similar in functionality to a Responder that takes a data
71file as a parameter. The difference is that with a Filter, both the data
72file and the Filter itself can be access controlled using the Web
73server's access control mechanisms, while a Responder that takes the name
74of a data file as a parameter must perform its own access control checks
75on the data file."
76
77 Which is fine, our access control checks will be "Is this database
78 defined user already logged on via our FCGI script?". We should have
79 total control over that. I was planning on using the FCGI auth
80 mechanism anyway.
81
82
83RESPONDER
84 web server sends FCGI_PARAMS
85 CONTENT_LENGTH
86 web server sends input body FCGI_STDIN
87 fcgi app sends result data over FCGI_STDOUT and error messages over FCGI_STDERR
88 it has to finish reading FCGI_PARAMS first
89 fcgi app sends FCGI_END_REQUEST(protocolStatus = FCGI_REQUEST_COMPLETE)
90
91
92FILTER
93 filtered file has last modified time
94 web server sets FCGI_DATA_LAST_MOD accordingly
95 web server sends FCGI_PARAMS
96 CONTENT_LENGTH FCGI_DATA_LAST_MOD FCGI_DATA_LENGTH
97 web server sends input body FCGI_STDIN
98 web servers sends file over FCGI_DATA
99 fcgi app can ignore FCGI_DATA and use it's own cached copy based on FCGI_DATA_LAST_MOD
100 fcgi app sends result data over FCGI_STDOUT and error messages over FCGI_STDERR
101 it has to finish reading FCGI_STDIN first, but not FCGI_DATA
102 fcgi app sends FCGI_END_REQUEST(protocolStatus = FCGI_REQUEST_COMPLETE)
103
104
105Soooo, FILTER might be slower anyway if we are caching the filtered file,
106or mmapping it, coz filter has to start sending the filtered file, even
107if it's to be served from cache. Plus no need to wait for FCGI_STDIN
108before spewing it out.
109
110
111Last update time for parameters, plus an update frequency. Once a minute.
112
113 NOTE - SSI is a bit more complex than what I'm currently using.
114 https://en.wikipedia.org/wiki/Server_Side_Includes
115 <!--#include virtual="menu.cgi" -->
116 <!--#include file="footer.html" -->
117 <!--#exec cgi="/cgi-bin/foo.cgi" -->
118 <!--#exec cmd="ls -l" -->
119. <!--#echo var="REMOTE_ADDR" -->
120 <!--#config timefmt="%y %m %d" -->
121 <!--#config sizefmt="bytes" -->
122 <!--#config errmsg="SSI command failed!" -->
123 <!--#flastmod virtual="index.html" -->
124 <!--#fsize file="script.pl" -->
125 <!--#if expr="${Sec_Nav}" -->
126 <!--#include virtual="secondary_nav.txt" -->
127 <!--#elif expr="${Pri_Nav}" -->
128 <!--#include virtual="primary_nav.txt" -->
129 <!--#else -->
130 <!--#include virtual="article.txt" -->
131 <!--#endif -->
132 <!--#set var="foo" value="bar" -->
133 <!--#printenv -->
134 https://www.w3.org/Jigsaw/Doc/User/SSI.html
135 Adds lots of others, including Java stuff.
136 Mine
137 <!--#lua lua="print(table[key])" -->
138 <!--#lua file="/path/to/script.lua" -->
139 <!--#lua virtual="https://example.com/script.lua" -->
140
141-------------------------------------------------------------------
142
143Account creation process in the database.
144
145Apart from the usual input validation of things...
146
147
148OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs
149 byte[] CreateUser(Dictionary<string, object> request)
150 Looks like their built in web front end, perhaps what is triggered by the console?
151 createdUserAccount
152 = ((UserAccountService)m_UserAccountService).CreateUser(scopeID, principalID, firstName, lastName, password, email, model);
153
154OpenSim/opensim-SC/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
155 An XML RPC interface to -
156 private UserAccount CreateUser(UUID scopeID, string firstName, string lastName, string password, string email)
157 account = new UserAccount(scopeID, UUID.Random(), firstName, lastName, email);
158 if (userAccountService.StoreUserAccount(account))
159 success = authenticationService.SetPassword(account.PrincipalID, password)
160 gridUserService.SetHome(account.PrincipalID.ToString(), home.RegionID, new Vector3(128, 128, 0), new Vector3(0, 1, 0));
161 success = inventoryService.CreateUserInventory(account.PrincipalID);
162
163OpenSim/opensim-SC/OpenSim/Services/UserAccountService/UserAccountService.cs
164 Looks like the console command handler.
165 create user [<first> [<last> [<pass> [<email> [<user id> [<model>]]]]]] - Create a new user
166 protected void HandleCreateUser(string module, string[] cmdparams)
167 Gathers console arguments, or prompts for them.
168 CreateUser(UUID.Zero, principalId, firstName, lastName, password, email, model);
169 public UserAccount CreateUser(UUID scopeID, UUID principalID, string firstName, string lastName, string password, string email, string model = "")
170 Looks almost identical to the OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs one above, but they add -
171 CreateDefaultAppearanceEntries(account.PrincipalID)
172
173
174
175account = new UserAccount(scopeID, UUID.Random(), firstName, lastName, email);
176 OpenSim/opensim-SC/OpenSim/Services/Interfaces/IUserAccountService.cs
177 public UserAccount(UUID scopeID, UUID principalID, string firstName, string lastName, string email)
178 Just holds the data in memory, in a dictionary I think.
179 OpenSim/opensim-SC/OpenSim/Services/UserAccountService/UserAccountService.cs
180 public bool StoreUserAccount(UserAccount data)
181 Stuffs the data into a new UserAccountData()
182 m_Database.Store(d)
183 As far as I can tell, just dumps this data into the UserAccounts table -
184 FirstName, LastName, PrincipleID, ScopeID, Email, Created, UserLevel, UserFlags, UserTitle
185 PrincipleID is their randomly generated with no thought to collisions UUID.
186 ScopeID is 00000000-0000-0000-0000-000000000000
187 Userlevel is 0 for most, -1 for Waki, determines if they can log on. Also higher for gods and things.
188 UserFlags, I think the only one is "64 god can login to this account using gods password.
189 UserTitle might default to "Local", or be configurable / and editable.
190 something something URL encoded "ServiceURLs" mumble
191 HomeURI=http%3a%2f%2fgrid.infinitegrid.org%3a8002%2f GatekeeperURI= InventoryServerURI=http%3a%2f%2fgrid.infinitegrid.org%3a8002%2f AssetServerURI=http%3a%2f%2fgrid.infinitegrid.org%3a8002%2f ProfileServerURI=http%3a%2f%2fgrid.infinitegrid.org%3a8002%2f FriendsServerURI=http%3a%2f%2fgrid.infinitegrid.org%3a8002%2f IMServerURI=http%3a%2f%2fgrid.infinitegrid.org%3a8002%2f GroupsServerURI=http%3a%2f%2fgrid.infinitegrid.org%3a8002%2f
192 Though most are either NULL, empty, or -
193 HomeURI= GatekeeperURI= InventoryServerURI= AssetServerURI=
194 Doesn't metion "active", which is always equal to 1 I guess.
195
196
197
198success = authenticationService.SetPassword(account.PrincipalID, password)
199 OpenSim/Services/AuthenticationService/AuthenticationServiceBase.cs
200 stores password details in "auth" table -
201 UUID
202 passwordSalt = Util.Md5Hash(UUID.Random().ToString());
203 passwdHash = Util.Md5Hash(Util.Md5Hash(password) + ":" + passwordSalt);
204 accountType = "UserAccount";
205 webLoginKey = UUID.Zero.ToString();
206
207
208
209gridUserService.SetHome(account.PrincipalID.ToString(), home.RegionID, new Vector3(128, 128, 0), new Vector3(0, 1, 0));
210 OpenSim/Services/UserAccountService/GridUserService.cs
211 Stores in database table GridUser
212 HomeRegionID, HomePosition, HomeLookAt
213 The other fields in that table -
214 UserID, LastRegionID, LastPosition, LastLookAt, Online (true or false), Login (timestamp or 0), Logout (timestamp or 0).
215
216
217
218success = inventoryService.CreateUserInventory(account.PrincipalID);
219 OpenSim/Services/InventoryService/XInventoryService.cs
220 Create a bunch of folders in the users inventory, of specific types.
221 rootFolder = ConvertToOpenSim(CreateFolder(principalID, UUID.Zero, (int)FolderType.Root, InventoryFolderBase.ROOT_FOLDER_NAME));
222 XInventoryFolder[] sysFolders = GetSystemFolders(principalID, rootFolder.ID)
223 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Animation) return true; return false; }))
224 CreateFolder(principalID, rootFolder.ID, (int)FolderType.Animation, "Animations");
225 FolderType.BodyPart, "Body Parts"
226 XInventoryFolder folder = CreateFolder(principalID, rootFolder.ID, (int)FolderType.CallingCard, "Calling Cards");
227 folder = CreateFolder(principalID, folder.folderID, (int)FolderType.CallingCard, "Friends")
228 CreateFolder(principalID, folder.folderID, (int)FolderType.CallingCard, "All");
229 FolderType.Clothing, "Clothing"
230 FolderType.CurrentOutfit, "Current Outfit"
231 FolderType.Favorites, "Favorites"
232 FolderType.Gesture, "Gestures")
233 FolderType.Landmark, "Landmarks"
234 FolderType.LostAndFound, "Lost And Found"
235 FolderType.Notecard, "Notecards"
236 FolderType.Object, "Objects"
237 FolderType.Snapshot, "Photo Album"
238 FolderType.LSLText, "Scripts"
239 FolderType.Sound, "Sounds"
240 FolderType.Texture, "Textures"
241 FolderType.Trash, "Trash"
242
243 Stores in database inventoryFolders ????
244 folderName, type, version = 1, folderID = UUID.Random(), agentID = principalID, parentFolderID = parentID
245
246
247
248
249CreateDefaultAppearanceEntries(account.PrincipalID)
250 OpenSim/Services/UserAccountService/UserAccountService.cs
251 protected void CreateDefaultAppearanceEntries(UUID principalID)
252 Creates a bunch of "Default *" body parts and clothes, Ruth 1.0, links them in Inventories current outfit folder.
253 Creates a AvatarWearable[] and puts them all in it.
254 AvatarAppearance ap = new AvatarAppearance();
255 ap.SetWearable(i, wearables[i]);
256 m_AvatarService.SetAppearance(principalID, ap);
257
258
259
260
261
262UserAccounts table -
263 UserFlags 64 is "allow gods to log in as me"
264 0xf00 is membershipType, unles there's a title. Only sent to viewers I think.
265 32 is Minors for estate banning purposes.
266 4 is Anonymous for estate banning purposes.
267 1 is AllowPublish in profile, but userprofile has this as separate field.
268 2 is MaturePublish in profile, but userprofile has this as separate field.
269Presence table -
270 UserID varchar(255)
271 RegionID char(36)
272 SessionID char(36)
273 SecureSessionID char(36)
274 LastSeen timestamp
275tokens table (I think this is actually used for something) -
276 UUID char(36)
277 token varchar(255) current example looks like a UUID.
278 validity datetime
279userdata (empty, can't find any actual usage in the source code, part of profiles) -
280 UserId char(36) primary index
281 TagId varchar(64) primary index
282 DataKey varchar(255)
283 DataVal varchar(255)
284auth.webLoginKey seems to be some sort of passwordy type thing, though perhaps not actually hashed, rarely used, none of IG members have one.
285
286
287PLAN-
288. username
289. password
290. create login
291
292.check if it's a proper two word name
293.login -> check if it's an existing account, get their UUID.
294 create toke_n_munchie
295 write session record
296
297create -> new user
298 create new UUID
299 check if it's an existing UUID
300 dbCount(, "UserAccounts", "PrincipleID='new-UUID'")
301 loop until we get a new one
302 create toke_n_munchie
303 write session record
304
305
306 Create ->
307 (wait a few seconds before showing this page)
308. email
309. email again
310. password again
311. DoB
312. accept terms of service
313. claim to be an adult
314. confirm / cancel
315
316 New user
317 UserAccounts.FirstName = ???
318 UserAccounts.LastName = ???
319 UserAccounts.Email = ???
320 UserAccounts.Created = timestamp
321 UserAccounts.PrincipleID = randomly generate UUID, but check for collisions with other accounts.
322 It's a UNIQUE KEY.
323 UserAccounts.ScopeID = 00000000-0000-0000-0000-000000000000
324 UserAccounts.Userlevel = -200
325 UserAccounts.UserFlags = 64
326 UserAccounts.UserTitle = newbie
327 UserAccounts.ServiceURLs = ""
328 UserAccounts.active = 0
329
330 auth.UUID = UserAccounts.PrincipleID
331 It's a PRIMARY KEY.
332 auth.passwordSalt = Util.Md5Hash(UUID.Random().ToString())
333 auth.passwdHash = Util.Md5Hash(Util.Md5Hash(password) + ":" + passwordSalt)
334 auth.accountType = "UserAccount"
335 auth.webLoginKey (varchar(255)) = "00000000-0000-0000-0000-000000000000"
336
337 userdata.UserId = UserAccounts.PrincipleID
338 userdata.TagId = "account creation data"
339 It's a UNIQUE KEY
340 userdata.DataKey = "DoB"
341 userdata.DataVal = ???
342
343 userdata.UserId = UserAccounts.PrincipleID
344 userdata.TagId = "account creation data"
345 userdata.DataKey = "timezone"
346 userdata.DataVal = ???
347
348 userdata.UserId = UserAccounts.PrincipleID
349 userdata.TagId = "account creation data"
350 userdata.DataKey = "Terms of service"
351 userdata.DataVal = "True"
352
353 userdata.UserId = UserAccounts.PrincipleID
354 userdata.TagId = "account creation data"
355 userdata.DataKey = "claims to be an adult"
356 userdata.DataVal = "True"
357
358
359 Validated via email
360 (wait a few seconds before showing this page)
361 UserAccounts.Userlevel = -100
362 UserAccounts.UserTitle = validated
363
364
365 Vouched for
366 userdata.UserId = UserAccounts.PrincipleID
367 userdata.TagId = "vouches"
368 userdata.DataKey = UUID of voucher
369 userdata.DataVal = timestamp of vouching
370
371 UserAccounts.Userlevel = -50
372 UserAccounts.UserTitle = vouched for
373
374
375 Admin approved
376 GridUser.UserID = UserAccounts.PrincipleID
377 It's a PRIMARY KEY.
378 GridUser.HomeRegionID = ???
379 GridUser.HomePosition = ???
380 GridUser.HomeLookAt = ???
381 GridUser.LastRegionID = ???
382 GridUser.LastPosition = ???
383 GridUser.LastLookAt = ???
384 GridUser.Online = False
385 GridUser.Login = 0
386 GridUser.Logout = 0
387
388 UserAccounts.active = 1
389 UserAccounts.Userlevel = 1
390 UserAccounts.UserTitle = Member / Local / whatever
391
392 Load the default IAR.
393
394
395-------------------------------------------------------------------
396
397https://project-awesome.org/aleksandar-todorovic/awesome-c
398 A curated list of C good stuff.
399
400https://wolkykim.github.io/qdecoder/
401 CGI library made by the qlibc guy, does support FCGI.
402 Might be a wrapper around the fcgi_stdio stuff I'm already using?
403
404
405https://danielmiessler.com/study/http/
406 A Security-focused HTTP Primer
407 Nothing much new except to say this about the Referer header -
408 "should not be used to make security decisions as it is controlled by the client"
409 Though others tell us to do precisely that. lol
410
411
412-------------------------------------------------------------------
413
414apt install libmariadbclient-dev libapache2-mod-fcgid libssl1.0-dev uuid-dev spawn-fcgi
415
416BTW, everything is some BSD licence variation, except MariaDB, which is
417some combination of GPLv2, 2+, 3, and BSD variants. With FOSS License
418Exception, which seems to mean "Oracles GPL isn't viral". Though my
419license is "fuck you viral GPL, that's not your decision to make for my
420fucking code" BSD.
421
422-------------------------------------------------------------------
423
424Install / update / upgrade.
425
426I could keep the version number around.
427 Include version numbers / branches of dependencies.
428 Update will grab any security updates for the installed version.
429 Upgrade will upgrade to a chosen later different version.
430 Downgrade will downgrade to a chosen earlier different version.
431
432Note that we are currently using the LuaJIT 2.1.0-beta3 branch of the
433main Luajit repo. Everything else is on their master branches.
434
435Bootstrap -
436 bootstrap.sh or bootstrap.bat
437
438 Build the LuaJIT that comes with our source. It "builds out-of-the
439 box on most systems" and has no dependencies, other than a C build system.
440
441 Or download a prebuilt LuaJIT from somewhere.
442
443 After toybox has been LuaJITized.
444
445 Build the LuaJIT that comes with our source. It "builds out-of-the
446 box on most systems" and has no dependencies, other than a C build system.
447
448 Similar should apply to toybox, though it's our LuaJITized version.
449 Will need a specific miniconfig for this that doesn't include sledjchisl.
450
451 Or download a prebuilt toybox+LuaJIT from a SledjHamr package repo.
452
453Install -
454 install.lua
455
456 Will need a pre flight check if the dependencies are installed.
457 It checks if the system is built and has source.
458 Build it all.
459 Do the usual copy stuff to a directory thing.
460 Run "sledjchisl -install" in that directory.
461 Which does the usual "check health of system and fix up problems" thing, then quits instead of keep running.
462 The health check should include making sure our database creds exist / work.
463
464Update / upgrade / downgrade
465 install.lua -update
466 install.lua -upgrade
467 install.lua -downgrade
468
469 Check if we are a binary only, or a source install.
470 wget new binaries / git pull new source
471 Toybox has a wget in pending, otherwise it only has ftpget.
472 Git is standalone outside of the system, but if you are
473 running from source, you likely have standard build tools
474 like git.
475
476
477Yeah I hate things that have their own packaging system, for needing to
478step outside the operating systems packaging system, and adding to the too
479long list of stuff I have to deal with manually, and now I are one. lol