Şifreli şifreyi awk ile kolayca çıkarabilirsiniz. Daha sonra ön eki çıkarmanız gerekir $algorithm$salt$
(bu sistemin, bugünlerde kaba bir şekilde zorlanabileceği için kesinlikle kullanımdan kaldırılmış olan geleneksel DES'i kullanmadığı varsayılarak).
correct=$(</etc/shadow awk -v user=bob -F : 'user == $1 {print $2}')
prefix=${correct%"${correct#\$*\$*\$}"}
Parola kontrolü için, temel C işlevidir crypt
, ancak erişmek için standart bir kabuk komutu yoktur.
Komut satırında, crypt
şifreyi çağırmak için bir Perl bir liner kullanabilirsiniz .
supplied=$(echo "$password" |
perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "$prefix")
if [ "$supplied" = "$correct" ]; then …
Bu saf kabuk araçlarında yapılamadığından, eğer Perl varsa, her şeyi Perl'de de yapabilirsin. (Veya Python, Ruby,… ne crypt
fonksiyon varsa çağırabiliyorsanız .) Uyarı, denenmemiş kod.
#!/usr/bin/env perl
use warnings;
use strict;
my @pwent = getpwnam($ARGV[0]);
if (!@pwent) {die "Invalid username: $ARGV[0]\n";}
my $supplied = <STDIN>;
chomp($supplied);
if (crypt($supplied, $pwent[1]) eq $pwent[1]) {
exit(0);
} else {
print STDERR "Invalid password for $ARGV[0]\n";
exit(1);
}
Perl olmayan gömülü bir sistemde küçük, özel bir C programı kullanırdım. Doğrudan tarayıcıya yazılan uyarı, derlemeye bile çalışmadım. Bu, sağlam bir uygulama olarak değil, gerekli adımları göstermek içindir!
/* Usage: echo password | check_password username */
#include <stdio.h>
#include <stdlib.h>
#include <pwd.h>
#include <shadow.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
char password[100];
struct spwd shadow_entry;
char *p, *correct, *supplied, *salt;
if (argc < 2) return 2;
/* Read the password from stdin */
p = fgets(password, sizeof(password), stdin);
if (p == NULL) return 2;
*p = 0;
/* Read the correct hash from the shadow entry */
shadow_entry = getspnam(username);
if (shadow_entry == NULL) return 1;
correct = shadow_entry->sp_pwdp;
/* Extract the salt. Remember to free the memory. */
salt = strdup(correct);
if (salt == NULL) return 2;
p = strchr(salt + 1, '$');
if (p == NULL) return 2;
p = strchr(p + 1, '$');
if (p == NULL) return 2;
p[1] = 0;
/*Encrypt the supplied password with the salt and compare the results*/
supplied = crypt(password, salt);
if (supplied == NULL) return 2;
return !!strcmp(supplied, correct);
}
Farklı bir yaklaşım, su
ya da gibi mevcut bir programı kullanmaktır login
. Aslında, yapabiliyorsanız, web uygulamasının ihtiyacı olan her şeyi yapmasını sağlamak için ideal olacaktır su -c somecommand username
. Buradaki zorluk, şifreyi şu şekilde beslemektir su
; bu bir terminal gerektirir. Bir terminali taklit eden normal araç beklenir , ancak gömülü bir sistem için büyük bir bağımlılıktır. Ayrıca, su
BusyBox içerisindeyken, çoğu zaman ihmal edilir, çünkü kullanımlarının çoğu, BusyBox ikilisinin setuid root olmasını gerektirir. Yine de, bunu yapabiliyorsanız, güvenlik açısından en sağlam yaklaşım budur.