# lib9p/idl/1995-9P1.9p - Definitions of 9P1 (Plan 9 2nd ed and 3rd ed) messages # # Copyright (C) 2024-2025 Luke T. Shumaker # SPDX-License-Identifier: AGPL-3.0-or-later # Plan 9 2nd and 3rd edition used a version of 9P lightly revised from # the 1st edition version, re-thinking authentication. # # 2nd edition documentation: # - https://github.com/plan9foundation/plan9/tree/2e-1995-04-05/sys/man/5 # - https://github.com/plan9foundation/plan9/tree/2e-1995-04-05/sys/man/6/auth # - https://man.cat-v.org/plan_9_2nd_ed/5/ # - https://man.cat-v.org/plan_9_2nd_ed/6/auth # # 2nd edition implementation references: # - https://github.com/plan9foundation/plan9/blob/2e-1995-04-05/sys/include/fcall.h (MAXFDATA) # - https://github.com/plan9foundation/plan9/blob/2e-1995-04-05/sys/include/libc.h (`ch` bits) # - https://github.com/plan9foundation/plan9/blob/2e-1995-04-05/sys/include/auth.h (auth matic) # - https://github.com/plan9foundation/plan9/blob/2e-1995-04-05/sys/src/fs/port/fcall.c (`stat`) # - https://github.com/plan9foundation/plan9/blob/2e-1995-04-05/sys/src/fs/port/fs.c (`offset:max`) # - https://github.com/plan9foundation/plan9/blob/2e-1995-04-05/sys/src/fs/port/portdata.h (`MAXDAT`) # - https://github.com/plan9foundation/plan9/blob/2e-1995-04-05/sys/src/libauth/convM2T.c (`auth_ticket`) # # 3rd edition documentation: # - https://github.com/plan9foundation/plan9/tree/3e-2001-03-28/sys/man/5 # - https://github.com/plan9foundation/plan9/tree/3e-2001-03-28/sys/man/6/auth # - https://man.cat-v.org/plan_9_3rd_ed/5/ # - https://man.cat-v.org/plan_9_3rd_ed/6/auth # # 3rd edition implementation references: # - https://github.com/plan9foundation/plan9/blob/3e-2001-03-28/sys/include/fcall.h (MAXFDATA) # - https://github.com/plan9foundation/plan9/blob/3e-2001-03-28/sys/include/libc.h (`ch` bits) # - https://github.com/plan9foundation/plan9/blob/3e-2001-03-28/sys/include/auth.h (auth magic) # - https://github.com/plan9foundation/plan9/blob/3e-2001-03-28/sys/src/fs/port/fcall.c (`stat`) # - https://github.com/plan9foundation/plan9/blob/3e-2001-03-28/sys/src/fs/port/fs.c (`offset:max`) # - https://github.com/plan9foundation/plan9/blob/3e-2001-03-28/sys/src/lib9p/srv.c (read `offset:max`) # - https://github.com/plan9foundation/plan9/blob/3e-2001-03-28/sys/src/libauth/convM2T.c (`auth_ticket`) version "9P1" from ./1992-9P0.9p import tag, fid, qid, name, errstr, o, ch, stat # CHMOUNT is undocumented (and is explicitly excluded from the 9P2000 # draft RFC). As I understand it, CHMOUNT indicates that the file is # mounted by the kernel as a 9P transport; that the kernel has a lock # on doing I/O on it, so userspace can't do I/O on it. bitfield ch += "28=MOUNT" # Authentication uses DES encryption. The client obtains a ticket and # a nonce-key from a separate auth-server; how it does this is beyond # the scope of this document. struct random = "8*(dat[1])" struct domain_name = "48*(txt[1])" struct des_key = "7*(dat[1])" struct encrypted_ticket = "72*(ciphertext[1])" # encrypted by auth-server with server-key struct cleartext_ticket = "magic[1,val=64] server_chal[random] client_uid[name] server_uid[name] nonce_key[des_key]" struct encrypted_authenticator_challenge = "13*(ciphertext[1])" # encrypted by client with nonce-key obtained from auth-server struct cleartext_authenticator_challenge = "magic[1,val=66] server_chal[random] replay_count[4]" struct encrypted_authenticator_response = "13*(ciphertext[1])" # encrypted by server with nonce-key obtained from ticket struct cleartext_authenticator_response = "magic[1,val=67] client_chal[random] replay_count[4]" # A 9P0 session goes: # # [nop()] # auth_tok=[session()] # attach(auth_tok) # ... #from ./1992-9P0.9p import Tmux # typ=48 ; removed #from ./1992-9P0.9p import Rmux # typ=49 ; removed from ./1992-9P0.9p import Tnop # typ=50 from ./1992-9P0.9p import Rnop # typ=51 #from ./1992-9P0.9p import Tsession # typ=52 ; revised, now has typ=84 #from ./1992-9P0.9p import Rsession # typ=53 ; revised, now has typ=85 #from ./1992-9P0.9p import Terror # typ=54 ; never existed from ./1992-9P0.9p import Rerror # typ=55 from ./1992-9P0.9p import Tflush # typ=56 from ./1992-9P0.9p import Rflush # typ=57 #from ./1992-9P0.9p import Tattach # typ=58 ; revised, now has typ=86 #from ./1992-9P0.9p import Rattach # typ=59 ; revised, now has typ=87 from ./1992-9P0.9p import Tclone # typ=60 from ./1992-9P0.9p import Rclone # typ=61 from ./1992-9P0.9p import Twalk # typ=62 from ./1992-9P0.9p import Rwalk # typ=63 from ./1992-9P0.9p import Topen # typ=64 from ./1992-9P0.9p import Ropen # typ=65 from ./1992-9P0.9p import Tcreate # typ=66 from ./1992-9P0.9p import Rcreate # typ=67 from ./1992-9P0.9p import Tread # typ=68 from ./1992-9P0.9p import Rread # typ=69 from ./1992-9P0.9p import Twrite # typ=70 from ./1992-9P0.9p import Rwrite # typ=71 from ./1992-9P0.9p import Tclunk # typ=72 from ./1992-9P0.9p import Rclunk # typ=73 from ./1992-9P0.9p import Tremove # typ=74 from ./1992-9P0.9p import Rremove # typ=75 from ./1992-9P0.9p import Tstat # typ=76 from ./1992-9P0.9p import Rstat # typ=77 from ./1992-9P0.9p import Twstat # typ=78 from ./1992-9P0.9p import Rwstat # typ=79 from ./1992-9P0.9p import Tclwalk # typ=80 from ./1992-9P0.9p import Rclwalk # typ=81 #from ./1992-9P0.9p import Tauth # typ=82 ; merged into Tsession #from ./1992-9P0.9p import Rauth # typ=83 ; merged into Rsession msg Tsession = "typ[1,val=84] tag[tag,val=0xFFFF] chal[random]" msg Rsession = "typ[1,val=85] tag[tag,val=0xFFFF] chal[random] server_name[name] server_domain[domain_name]" msg Tattach = "typ[1,val=86] tag[tag] fid[fid] uid[name] aname[name] ticket[encrypted_ticket] auth[encrypted_authenticator_challenge]" msg Rattach = "typ[1,val=87] tag[tag] fid[fid] qid[qid] rauth[encrypted_authenticator_response]"