Re: path name limits

Matthias Paul <[email protected]>
Newsgroups gmane.os.freedos.devel
Organization Aachen University of Technology (RWTH), Germany
Message-ID <[email protected]>
On 2002-10-24, Bart Oldeman wrote:

>>>> What are tha path name limits imposed on freedos? MS-DOS
>>>> has 66 and DR-DOS has 63, I need a few more :(.
>
> This wasn't me.
>
>>> Any _DOS_ (should) limits _path_ to 67 characters and name to 8.3
>>> characters. This gives 67+\+8+.+3=80 characters for full path.
>
> And this wasn't me.
>
> I wonder how you got Arkady and me confused. As if we were the same
> person and me having had lots of discussions with my alter ego :)
> Did you do the quoting manually?

I'm sorry, Bart, my fault. I was just a bit too tired...
Sh**, where's the coffee, now? ;-)

I am only subscribed to the digest version of the FreeDOS list
(since I want this format for archiving purposes, and have too
little bandwidth to receive both formats on my private account -
I don't want to use workplace infrastructure for personal interests).

Yes, all my mails get quoted, edited, and formatted manually.

Now, you might better understand, why I sometimes get quite frustrated
about some careless posters' HTML stuff and TOFU quotings in this list -
it costs the valueable time of other readers to skip or even delete
all this redundant stuff.

> The 10 reserved bytes are not reserved anymore -- they are used as
> access/creation times and dates by various FAT filesystems and
> documented in the MS specification.

Yes, I know, this imposes some problems and that's why I said: optional.
BTW. At source code level, it is optional in DR-DOS as well, although
the corresponding conditional is always set true.

(Actually, my original post was about giving a bit more background on
special cases of the maximum path length in DR DOS - to flesh out
a little, what you and Arkady already wrote. I think, it is always
good to be aware of non-obvious exceptions/extensions to the basic
MS-DOS/PC DOS concepts, so things can be taken into account in other
software developments. It was not directly about adding password
support to FreeDOS now, although I certainly like that idea, that's
why I will go into some better details here.)

Still, with a bit of heuristics it is possible to combine VFAT long
filenames and DR-DOS passwords on the same volume (except for on FAT32
volumes, IIRC) and distinguish between them. In 1999 I developed a
version of the DR-DOS kernel which could cope with both, but it was
too late to get published - the change was not more than maybe a few
dozend bytes, so it should be similarly easy in FreeDOS (assuming it
would otherwise support password protected files already).

> About file passwords. Are they truely secure? One would have to
> encrypt the file itself too, as far as I can see, because otherwise,
> given the nature of DOS as a real mode OS it will always be possible
> to circumvent it using BIOS int13 (and if DRDOS hooks the BIOS you
> could just change the int13 vector to use the original int).

No, the file contents is not encrypted, but it would be possible to
add this (more thoughts on this much further below).

DR-DOS hooks INT 13h as every DOS does (or should do), if for nothing
else, then to deblock multi-sector access to the disk in some cases,
and to first flush the cache in case someone bypasses DOS. Do you mean
INT 2Fh/AH=13h? At least on a secured system, the special $SECURE$
device driver traps this.

For clarification, although both features can be combined, system security
is an optional component of DR-DOS (to be installed during SETUP/INSTALL).
The default security module shipping with DR-DOS is only a single-user
security (and Personal NetWare, yet another component, can be used
to add some aspects of "multi-user", then), however, DR-DOS also works
with the multi-user security component as found in DR DOS "Panther"
and (in another form) in the Multiuser DOS family (including REAL/32).

The password feature in DR-DOS works with or without system security,
but without it, it provides only a very light protection, which may
do a good job against theft on occasion or just human error.
/With/ system security installed it is still nothing for really critical
tasks, just because - as you already pointed out - DOS is an open system.
Knowledgable people like you and me would be able to break into the
system, no question, just because in the worst case we could always
patch around in the running kernel or analyse the disk surface sector
by sector under a different OS. (Since this is so, I can also describe
some of the used mechanisms without risking to tell secrets - it just
won't compromise the system any more than it is compromisable by the
inherent limitations of security under DOS "as is". Still, I think,
it is a reasonable good protection system for use under DOS, much
better than having only the Read-Only and Hidden attributes to play
with (as under MS-DOS/PC DOS), and with a few changes it might become
even better with Linux underneath.)

Password protected files and directories under DR-DOS can easily
be accessed by just booting up any DOS-system, which is not
"password-aware". Just try MS-DOS or PC DOS (or FreeDOS).
But this obvious security loophole exists only as long as
the DR-DOS system security is not enabled.
If it /is/ enabled, you will not be granted access to the
secured partitions without entering the correct system
password. The security module (SECURITY.BIN/SECURITY.OVL)
is loaded as a special type of driver through the preload API,
then it hooks into the operating system (since it relocates
itself several times, this is quite sophisticated). You will
be prompted to enter the password while the system boots up,
and there's no way to bypass this (other then booting from
floppy and trying to patch around directly on the harddisk's
disk surface).
Booting other operating systems, you will not even see these
secured partitions, FDISK will show them as "NON-DOS" or
"DR-DOS secured" partitions (depending on which version of
FDISK you use), and (since Novell DOS 7+) even changing the
partition types back to something recognized by other OSes
won't help you any further (the old DR DOS 6.0 security
was easily vulnerable there).
System security will change the partition types 0xh to Cxh
or Dxh (remember the trick to misuse the C5h partition ID
to utilize up to 8 Gb of disk space for DR-DOS while not
wasting the remaining space for other OS?). In addition to
just changing the partition type, it scrambles the boot sectors
and, I think, parts of the FAT, so it is not easily possible
to bypass system security just by changing the partition type.
(With a fair amount of time and knowledge of the FAT file system
internals and advanced disk editors it /is/ possible to break
into the system and try to discover the seemlingly damaged
partitions, though. So, the system has inherent limitations,
but still convenient to have for home or office desktop use
and areas were its limited security is sufficient.)

Once you have logged in to the system (or system security
was not activated in the first place, so you did not have
to log in first), password protected files or directories
will occur has hidden files under MS-DOS/PC DOS, while under
DR-DOS they will occur as hidden files only with ATTRIB and
similar tools. Normal tools like DIR will show them just
as if they were usual files.

Now, in case you want to access a file, the kernel tries to
open the file and recognizes that it is password protected
by the info stored in the directory entry.
If the user has appended a password to the filespec using
the semicolon syntax, the hash of this password is compared
with the hash of the original password stored in the
directory entry. If they match, access is granted according
to the access permissions as detailed in another entry in
the ten reserved bytes in the directory entry. If you are
not permitted to open the file the way you try to open it,
an "access denied" error will be returned.
There are Read/Write/Delete/Execute permissions for each
of the three levels World/Group/Owner. When the multi-user
security is loaded, the system will also store the current
owner ID in yet another entry in the reserved area and it
will distinguish between these three hierarchy levels.
If you have a default DR-DOS system, all three levels will
be set to the same permission pattern, and only the owner
permissions will be used on query. The owner ID is zero on
a single-user system. The Execute flag works as a Read
permission in normal issues of DR-DOS, as this is only
used under DR FlexOS (and NetWare).
In case you tried to open the file for read-write access,
gave the correct password, and have read and write permissions,
everything is fine (given that the read-only file attribute
is not set - not to be mixed up with the permission flags,
this becomes more important in case the various file sharing
modes for concurrent file access (SHARE) have to be taken
into account as well).
If you would only have read permissions, you will receive an
error. If you would try to open the file in read-only mode,
you will be granted access to the file. If the password is
not specified or invalid, no access will be granted at all
(there's a "second choice" those, see below).

There are special hooks in the kernel, that is, the kernel
advertises all this stuff to optionally loadable external
modules (INT 2Fh/AX=102xh). If they are loaded, they can take
over and make a decision, otherwise the kernel does it itself.
This undocumented interface is vulnerable, but it is quite
cryptic and AFAIK it cannot easily be taken over by simple
TSRs or so because certain other conditions must be met
first. Anyway, it is definitely not 100% bullet-proof.
But, again, to get this far, you will already have to log in
to the system as a whole, so this only works, once the system
is already up and running. And since you can configure the
DR-DOS screen saver LOCK to ask you for a password (if you
don't specify one, it will compare your input with the global
password, which I will explain in a minute), running but
unattended systems are quite safe as well.
The default password handling in the kernel does not consume
much memory, a few hundred bytes, maybe. So this does not
cause any "bloating". This way, you can plug-in multi-user
or network security modules, or update the security mechanisms
with more sophisticated ones (interface with Linux for example). 

Anyway, if the password hashes do not match, there is one
fall-back mechanism so that you can still work with password
protected files from inside of applications which do not
support the semicolon syntax in any way (there always has
to be a fall-back system if you add extensions to DOS,
since there are always application programmers, which are
not aware of the extensions, and if you lock their applications
out completely, you won't gain much):

The kernel compares the file's password hash with the hash
of the so called global password. By default, this password
is not set, so you still won't get access to password
protected files (but you regain control to the system
in case this is used for the screen saver LOCK). However,
the external DR-DOS PASSWORD utility allows you to
set/change/unset the global password using the
PASSWORD /G and /NG options.
When the DR-DOS system security module is loaded and the
one-time-login feature is activated, the password you
used to log into the system automatically becomes the
global password.
Assume you would protect all your private files with the
password "Bart" and I would protect all my private files
with the password "Matthias", if you would log in to the
system as Bart, the system would only grant access to
all unprotected files, all files which are protected
with "Bart" (no need to specify "Bart" all the time,
since this is the global password), and all files,
for which you will explicitly specify a different
password using the semicolon syntax.
If I specify "Matthias" as a password when I log in,
I cannot access your files unless I know your password
and either change the global password to "Bart" or append
";Bart" to all the files I want to access.

(Of course, with multi-user security installed, group
associations have to be taken into account as well.
This is handled by an encrypted database maintained
by the security module. So this is outside the scope
of the kernel.)

When both, the individual file password and the global
password do not match the password associated with
the file, the kernel will return the error "password
protected" or "invalid password" (I would have to look
up the actual error number).
The calling application is now free to just display
the error and skip the file, return to the prompt, or
otherwise abort the action (similar to trying to open
a file for read-write which has the read-only file
attribute set), or it can display a prompt to enter
the correct password. Once it is entered, this will
be appended to the filespec using the semicolon syntax
and the application will try to open the file again.
If the password is correct, the kernel will now grant
access (according to the permission flags detailed
above), otherwise you will get the same error again.

On user level, there are two ways to assign passwords to
files and directories:

You can use the PASSWORD utility, which has a number of
options to set/change/unset file or directory passwords
(the /V option is not enabled in normal issues):

|PASSWORD R2.00 (981224) Display or change password protection level
|Copyright (c) 1987,1998 Caldera, Inc.  All rights reserved.
|
|PASSWORD [/Help] [@][d:][path][filename.ext] [/R|W|D|P|V|G[:password]] [/N][/S]
|
|  /R[:password] Password will be required to read, write or delete the file
|  /W[:password] Password will be required to write or delete the file
|  /D[:password] Password will only be required to delete the file
|  /P[:password] Password will be required for all access to the directory
|  /V[:password] Password will be required for all access to the volume label
|  /G[:password] Set global default password
|                Use '*' in place of password to request hidden entry: eg. /R:*
|
|  /N            Remove password protection from file
|  /NP           Remove password protection from directory
|  /NG           Remove global default password
|
|  /S            Operate on files or directories in subdirectories
|
|Multiple files may be specified on the command line.
|Use '@' to specify that the filename that follows is the name of a file list.

In DR DOS "Panther" and Multiuser DOS, there is also an XATTRIB
utility which looks similar to:

|XATTRIB R1.01 (921016)  Change file access permissions
|Copyright (c) 1991,1992 Novell Inc.  All rights reserved.
|
|XATTRIB [/Help] [@][d:][path]filename[.ext] [/switches]
|
|  /A:name       Change file owner to be name, where name is
|                the login name of the new owner
|  /B            Brief - display file name only
|  /D            Operate on directories, not files
|  /F            Display or change default file create permissions
|  /OGW:RWD      O=Owner, G=Group, and W=World (left of ':')
|                R=Read, W=Write, and D=Delete (right of ':')
|  /P            Prompt before operating on each file,
|                or paginate if displaying only
|  /S            Search for files in subdirectories
|  /U:name       Only operate on files with given owner or group name
|
|The file specification is the drive, path and name of file(s) for which
|access permissions are to be changed (wildcard and multiple filenames
|allowed). Use '@' to specify that the given file contains a file list.

Alternatively, file and directories will implicitly become
password protected when you create them while the given
filespec contains a password. In this case, the file will
get maximum protection, that is, you will need the password 
to read/write/delete the file/directory again. Example:

   COPY autoexec.bat protect.bat;mypwd

will create a file named PROTECT.BAT, which has the password
"mypwd" associated with it. (Again, this is handled at /kernel/
level, COPY (COMMAND.COM that is) will just try to open
a new file using the filespec "protect.bat;mypwd" not
knowing anything special about passwords.)
Further, the file will have the hidden attribute set
(this is just so that the file is not "easily visibible"
under MS-DOS/PC DOS, but has no further influence on the
actual password mechanism, if you remove the hidden attribute,
the file will still be password protected - still, I suggest
not to change this, as it is part of the pattern for the
heuristics, I mentioned above). To access the file, say type
it, you will either need to specify the password:

   TYPE protect.bat;mypwd

or you will have to set the global password to "mypwd" using
PASSWORD /G. Since many DR-DOS tools (like XCOPY etc.) already
know about passwords (how come? ;-), they have a simply special
case added and will prompt you for the password when they
receive the "password protected" error code, while most
3rd party tools will just display some kind of generic
"access denied" error, when you try to access such files.

The same applies to directories, for example:

   MD mydir;mypwd

will create a password protected directory \MYDIR\.
If you try to make \MYDIR\ the current directory, you
will have to make "mypwd" the glocal password first,
or just specify the password in the filespec:

  CD mydir;mypwd

CD just passes its argument to the corresponding kernel
function, which takes care of the password stuff.

BTW. This is also the reason, why, as I explained in my
previous post, a simple

 CD y:=c:\drdos

under DR DOS 3.31 - 6.0 (up to 1992) allows to implicitly
assign floating drives similar to

 SUBST y: c:\drdos

(Another neat trick with passwords is to password-protect
the kernel files themselves, so noone can accidently
overwrite your kernel files, whilst the kernel in its
initial bootstrap phase (before IBMDOS.COM is loaded)
can read the files without problems. I added a new option
to my internal version of DR-DOS SYS /W[:password]
to automatically assign passwords to the relevant files
during SYSing.)

---

On 2002-10-25, Tom Ehlert wrote:

>> DR DOS 3.31 - 6.0 should have no problems to traverse through
>> directory structures of any depth, at least when using
>> relative paths.
>
> I wonder, how you implement
>
> INT 21 - DOS 2+ - "CWD" - GET CURRENT DIRECTORY
>         AH = 47h
>         DL = drive number (00h = default, 01h = A:, etc)
>         DS:SI -> 64-byte buffer for ASCIZ pathname
> [...]
> for directory size >= 64

Valid question. Assume, you are in a overly-long directory like

C:\1\2\3\4\5\6\7\8\9\0\1\2\3\4\5\6\7\8\9\0\1\2\3\4\5\6\7\8\9\0\1\2\3\4\5\

Under DR DOS 6.0 (1991), the PROMPT $P$G will display

C:\4\5\6\7\8\9\0\1\2\3\4\5\6\7\8\9\0\1\2\3\4\5\6\7\8\9\0\1\2\3\4\5>

So, it is truncating the string at the beginning. INT 21h/AH=47h will
return with CY set and AX=0003h "path not found", the 64-bytes buffer
at DS:SI, however, will be filled with

"4\5\6\7\8\9\0\1\2\3\4\5\6\7\8\9\0\1\2\3\4\5\6\7\8\9\0\1\2\3\4\5",NUL

If we would not use directory names with a length of 1 here, the
kernel would truncate the string, so that it always starts with a
full directory name, even if it would not use up all 64 bytes of
the buffer then. So, you can be sure, you won't get cutted directory
names. Usually, the corresponding emulated CDS entry will contain

"C:\",NUL

no matter, if you are in a normal directory or in an overly-long directory
I haven't tried to fiddle around with this now - it may contain other
strings at certain times. Also, I haven't tried with DR DOS 3.31 - 5.0
now, but it should be the same (or almost the same) as with DR DOS 6.0.

Under the Windows 9x/SE/ME GUI, the corresponding VM's CDS array contains:

"C:\",NUL

as well - but only, when you are in an overly-long directory, otherwise
it will contain the usual contents. In the former case, INT 21h/AH=47h
returns with CY set and AX=000Fh "Invalid drive". The DS:SI buffer is
not updated. The LFN-API still provides the long name, of course.

I assume, but have not tested, plain MS-DOS would return the same error.

BTW. An easy way to run into the scenario of too deep directory structures
is to create a directory tree which almost reaches the maximum length,
and then rename one of the parent directory names (RENDIR etc.) so that
it becomes longer than before - bang. So, it's even a problem for
DOS-only users, not taking advantage of DR DOS or Windows 9x...

Well, definitely interesting to document all this stuff for RBIL.
I once sent Ralf a few - still incomplete - notes about the DR-DOS
CDS handling, but that must have been seven or more years ago and
it didn't show up in RBIL (probably my English was too bad at that
time ;-). I should probably restate all that stuff and submit it again,
but then, he still has much more than a meg or two of recent stuff
still in his queue at the moment... ;-)

---

On 2002-10-25, Arkady V.Belousov wrote:

> I suggest Matthias mean next feature:
>
>    setcurdir(path1);
>    open(filepath2);
>
> where path1 less than 67 and path1+filepath2 > 80 and filepath2
> is a relative path.

Yes.

---

On 2002-10-25, Steffen Kaiser wrote:

> You would need to make known to the kernel that the right-hand drive
> letter is a logical one, too, instead of a physical one. (Hence your
> reference to the flags??)

Yes.

> You can bypass these problems using UNC, e.g.:
>
>> Y: =
>> C:\1\2\3\4\5\6\7\8\9\0\1\2\3\4\5\6\7\8\9\0\1\2\3\4\5\6\7\8\9\0\1\2
>> Z: = Y:\A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
>
> Z: = \\?\-Y:\A\B\ ...
>
> It is actually derived from WinNT4's filename-mangle-bypass notation:
> \\?\C:\...

What do you mean by filename-mangle-bypass notation?

> Now you won't need to tag those entries particularily in order to let
> the kernel know that the right-hand drive letter is to look up as
> logical drive letter again (transitiveness).

Hm, I don't see how we could avoid that at the moment in one way or
the other. I'm probably missing some important aspect of your idea.
Before I start speculating, could you explain this in better
details, please?

> Because \\? is in invalid UNC path otherwise, you can play nice things
> with it. Also, because it's UNC now, most programs should keep their
> hands (er, bytes) away from these drives.

That /might/ be a good thing, indeed.

But I am not completely sure, if it would /always/ be a good thing
to have - I guess, this needs testing with some real world programs
like NC, XTREE, etc. If they could be fooled into believing the
right-hand drive letter (Y: in the example) would be a true drive
letter, but without starting to do nasty low level things with
it, it might even be good to let them use the entry as if it was
a normal one...
On the other hand, when they start making assumptions about which
partition drive Y: might be associated with, we might get into
trouble - but could they reasonable make such assumptions?

Right now, I just don't know. Any pro's and con's?

> I would actually prefer having something like this:
> You, the user, tell the kernel passwords beforehand, which are
> automatically applied to a range of files/directories on access. If
> you enter the wrong or none password, you get garbish. Easy, nifty,
> few traces, no checksums, no permission denied. However, would need
> block-encryption, passwords need to be kept in memory, automatization
> is limited, performance drop.

This sounds similar to the encryption method used by tools
like PKZIP. The idea is as follows: Don't store the password
(or a derivation code, which is used to perform the encryption,
or not even a checksum) anywhere, so noone can find that place
and read/reset/modify the value.
Only the user, who wrote the file knows the password, and if he
does not use the same password on any later access to the file,
the password, which is used as sieve for the encryption, will
only create binary garbage (always assuming we would use a
non-trivial encryption method). This can be very dangerous
for the stability of the data or the system, but at least
it does not compromise the security. It's the responsibility
of the calling application/user to take care of this.
If that password is still physically stored somewhere (not just
in the head of the user), it is again not in the responsibility
of the kernel to hide it, that's up to the user/application etc.
and since every application can store it somewhere else and
in a different format, it won't be easy to derive a pattern
for a global attack from it. If one password is found by an
intruder, the corresponding file is compromised, but not
the system. Is this more or less a description of what
you suggest?

As far as I see it, it would be possible to add something like
this to the existing "DR DOS password model" as well, it just
hasn't been done yet.
I think, the most difficult part would be the encryption itself,
which should be moved into an external module (maybe a DPMS
enabled driver, so it runs in Extended Memory in Protected Mode?).

I think, it would be very useful to have a new file-by-file flag
in the filesystem, something like ahypothetical file attribute
"Encrypted". If this attribute is set, the correct password
(1 to 8 characters) is required to recreate the original
contents of the file - the password itself is not stored
anywhere in the filesystem, but could be given in the filespec
similar to DR DOS access passwords. (This means, fragments of
the password may be floating around in memory or disk, but not
"inside" the filesystem.)

Hm, if we could assume the access password and the encryption
password could always be the same (so we could use the same
syntax for both of them), and if the encryption is done with
the original verbatim password and only the hash codes are
optionally stored in the filesystem (for the permission system),
you could still not derive the original password to decrypt
the file when you would find out the 16-bit hash (which is
stored on disk). Even resetting the hash on disk will break
the permission system, but not the encryption system. The
hash would be kind of a checksum over the password, but
with up to 8 bytes for the actual passwords and only 2 bytes
for the hash, I guess, this leaves enough false matches
to not allow unauthorized encryption. If the encryption
althorithm is good enough, it should not be possible to
derive any pattern from it, should it?

Of course, adding a new "Encrypted" file attribute will
break some low level disk tools, but maybe it could be
added to the access permissions, where 4 bits are still
unused. Well, this may break some heuristics to distinguish
between LFNs and password protected files, but it might
be possible to further refine the heuristics...
Not storing an "Encrypted" flag at all, you would have
the problem to tell apart, which files should get encrypted
and which should not. For example, encrypting the kernel
files or some other binary files would have fatal
consequences in normal use. So, how ever this flag will
have to be stored, it must be stored somewhere.
Another issue is that one file can only have one encryption
key (in this model), so it really seems like a good idea
to combine this with access permissions somehow, assuming,
that whoever is granted access to the file will then also
have the correct key to encrypt it.
(If someone breaks into the permission system without
actually knowing the password (only the hash) and then
only receives binary garbage, I guess, we can safely
assume this to be his own fault. ;-)

Greetings,

 Matthias

-- 
<mailto:[email protected]>; <mailto:[email protected]>
http://www.uni-bonn.de/~uzs180/mpdokeng.html; http://mpaul.drdos.org

"Programs are poems for computers."
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.