[Toybox] [CLEANUP] makedevs

2014-06-25 Thread Rob Landley
Commit 1362: http://landley.net/hg/toybox/rev/1362

First question: Are there any test command lines I can use for this?

The 64 byte limitation on name is arbitrary, it's the start of the
string so we might as well just null terminate and use that memory.

The help text says to feed '-' to unnecessary fields, but scanf aborts
when it hits '-' for %u, so if you feed '-' in any of the last 5 fields
the rest of them are ignored. Might as well just tell them not to supply
unnecessary fields?

We do no error checking if they feed letters into the numeric fields?
Ok... (Fixing this seems to involve adding an %n after very field, and
then there's the pass in - bit so I'd have to test for and _not_
complain about that... Not sure it's worth it? The lack of properly
created devices wouldn't exactly be subtle and the only users of this
are not just sysadmins but system developers)

We skip leading / but not leading ../../.., do we really care about
restricting the mknod to within -d (or under current directory)? Because
if so we can abspath() both arguments and strstart() to enforce it. (I'm
_guessing_ no, since this has to run as root anyway.) Meanwhile, change
the if (*a == '/') a++; into a while() so we at least catch // paths.
(Unless we _want_ to be able to say // if they run mknod from /home
instead of / and they didn't specify -d... What's the intended behavior
here? There's no spec.)

Major and minor numbers on devices went beyond 8 bits each years ago.
Dunno if lanana has any, but the sycall certainly does, so the invalid
line check isn't quite right.

This code initializes mode to default 755, which then gets overwritten
by the sscanf. The only time that's useful is if sscanf() stops parsing
before writing that (say the line is _just_ dev/filename f for
example). But user[] and group[] aren't initialized, so if they don't
get filled out we have random stack crap in them, and then *group will
at best fail the lookup...

How _do_ we handle short lines? What's the shortest line that makes
sense? I guess we need at least node and type to create zero length
files? Except 'f' expects the file to already exist? What exactly is
that _for_? You can specify ownership and permissions for initramfs
without root access when using the kernel's gen_init_cpio, and you can
similarly specify ownership and permissions out of band for mksquashfs
and genext2fs. I do all three in Aboriginal Linux, see
image_filesystem() ala
http://landley.net/hg/aboriginal/file/38095bbf7794/sources/functions.sh#l375

Back to shortest useful line, block or char devices need major/minor,
so instead of the  255 test, it should be if the value returned by the
scanf = 3 do the getpwnam() stuff, and = 4 do the getgrnam() stuff?
Meh, just init *user = *group = 0 so the current test actually works...

Possibly there should be a lib function for xgetpwnamuid(), or have
xgetpwnam() automatically call xgetpwuid() as a fallback, but I'll worry
about that one later because that's involves looking at the other
existing users pf getpwnam() and getpwuid() to see what they're doing.
In the meantime, looking up user and group info seems unnecessarily
verbose inline, fixing it brings up the next issue: warnings vs errors!

The warning/error mix here is... odd? We exit on user or group lookup
failure, but can't create directory or chmod/chown is just a warning?
I'm unsure of the intent here? What are the criteria for a fatal error
vs continuing?

Also, why do some perror_msg() lines include line number, but others
don't? If the logic is don't need the line number when we say the
filename... they all say the filename?

(I thought about using toys.rebound to continue instead of exiting so we
could use the xfunctions() as warnings instead of errors, but between
the when do we exit vs continue and the line numbers, I didn't. The
behavior is not consistent enough to factor out.)

Speaking of library functions, there's a wfchmodat() that prints a
warning if it can't do it, but not a wfchownat(). I looked at the
chown/chgrp commands under toys/posix and they couldn't immediately
benefit from this (due to a -f flag suppressing errors), so stick it on
the todo list...

Why is do we call chmod() right after feeding mode to mknod()? Right,
let's move the chown/chmod logic to the end of the loop so it's common
code we can fall through to instead of being repeated three times... The
mknod() loop is going out of its way to allow a cnt of 0 to be
synonymous with 1? Is that expected behavior? (There's no spec for this
command, and no test cases...) Except if it _is_, why would incr = 0
screw up this line:

  dev = makedev(major, minor + (i - st_val) * incr);

Because the most obvious way to get cnt 0 is a short line that doesn't
specify all the fields, so we leave it at the default value (initialized
to 0), yet incr is _after_ that, and also initialized to 0, but incr 0
means minor is always the same for all the nodes we create...

Note: the - advice in the help text still 

[Toybox] [CLEANUP] mkpasswd.c

2014-06-25 Thread Rob Landley
Commit 1363: http://landley.net/hg/toybox/rev/1363

Ok, starting with toys/pending/mkpasswd.c:

The is_salt_valid() function is only called from one place, and using a
regex to check isalnum() or two punctuation characters is a bit
overkill. (Since we did not use TOYFLAG_LOCALE we're in the C locale,
and thus isalnum() has predictable behavior defined by the C99 spec,
sections 7.4.1 and 5.2.1.1.) So zap that function and replace it with a
for loop at the call site.

We don't need -m help when we can put the list of supported types in
the help text itself. (Unless this is used programmatically to
autodetect support? The ubuntu version outputs a lot of extra verbiage
that would make parsing hard, and the busybox-1.19.0 I have lying around
doesn't support -m help at all?) I've yanked it for now, I can put -m
help back if anybody's actually using it...

This calls get_salt() which is a function in lib/password.c, a pending
library function. So let's clean that up.

get_salt:

  - Use libbuf instead of a local buf[]
  - The bit at the beginning with the if/else staircase can use a table.
  - Why is offset always 3? Even in the xase of algo=des where we
only added one $, we return an offset of 3. I'm going to assume
that was a mistake.
  - We don't need to track offset, just retain the initial salt
starting point and use pointer subtraction. So new char *s = salt;
  - loop on ARRAY_LEN(), do the work in the loop, and return -1 if the
loop exits.

So, move the prototype from lib/portability.h to lib/lib.h to track
which functions have been cleaned up.

Back in mkpasswd.c, right after calling get_salt() we overwrite the
returned salt with command line argument salt if we have it, so we read
entropy from /dev/urandom but didn't use it. Given how often that's a
finite resource on embedded devices this makes me uncomfortable, but
I'll leave it for now...

Why do we dup2() TT.pfd instead of using that as what we read from? If
it was never set it'll be 0, which is stdin anyway. (Also, if you fed
the old code -P 0 it would dup it, then close stdin. Oops?) Ah, I see:
it's because read_password() doesn't let us control the fd it reads
from, and we want -p to be able to specify a tty. (And here's _another_
pending library function I need to clean up... Eh, leave it for now.)

Ok, change the FLAG_P test to if (TT.pfd) and then we don't close stdin
if they go -P 0. Don't bother saying STDIN_FILENO, just use 0.

You know, int offset and int i don't overlap in scope, just have the top
one be int i. (And it doesn't need to be initialized because get_salt()
assigns to offset as the first use.

We don't need to strcpy the first argument to toybuf in the else case,
just put an ? : in the call to crypt.

So that's the cleanup on mkpasswd itself. Still have read_password() to
do in lib/password.c, but other than that the command's ready to be
promoted. (To other I guess, since it says No standard and thus
presumably is not in LSB? Yeah, not in posix or LSB. Apparently it comes
from the whois package, for no readily apparent reason...?)

Rob
___
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net


Re: [Toybox] [CLEANUP] mkpasswd.c

2014-06-25 Thread Isaac Dunham
On Wed, Jun 25, 2014 at 11:02:03PM -0500, Rob Landley wrote:
 We don't need -m help when we can put the list of supported types in
 the help text itself. (Unless this is used programmatically to
 autodetect support? The ubuntu version outputs a lot of extra verbiage
 that would make parsing hard, and the busybox-1.19.0 I have lying around
 doesn't support -m help at all?) I've yanked it for now, I can put -m
 help back if anybody's actually using it...

I'd just been looking into bcrypt support, where it theoretically
could be handy. bcrypt is supported on musl, some patched versions
of glibc, and a lot of non-linux systems.
To support it, we can either advertise bcrypt support everywhere and
fail sometimes or else probe for it.

Relevant information:
bcrypt is obtained via a salt starting with:
$2y$NN$
where NN is a 2-digit number not less than 04 nor more than 31 (at present),
limiting the number of rounds.
musl limits it a bit lower (I think ~20?); even 16 rounds takes a loooggg
time on an Atom N270@1.6 GHz, while 4-8 rounds is practically instant.

I'd suggest setting rounds to 8 at minimum, 12 at maximum.

Following this you need 22 characters of the usual sort for a salt;
traditionally it's terminated with a '$', but musl at least does not
require this.

Thanks,
Isaac Dunham
___
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net