* big restructering + feature enhancements

+ added auth_<method>.c, each basic auth-method has now
      its own implementation-file
    + added -auth - flag:
        - list      - lists all available methods
        - none      - no auth, like -nolock
        - passwd    - standard login, possible shadowsupport
        - pam       - use pam for authentification
        - md5:hash  - provide a md5-hash for authentification
* support for 'shadow'-passwords is part of the passwd authmodule

--HG--
extra : convert_revision : svn%3Aeebe1cee-a9af-4fe4-bd26-ad572b19c5ab/trunk%407
This commit is contained in:
mathias 2005-05-07 18:58:56 +00:00
parent a79727b9b2
commit e199e274c3
10 changed files with 868 additions and 220 deletions

View file

@ -1,4 +1,17 @@
Version 0.2
Version 0.5
2005-05-07:
* big restructering + feature enhancements
+ added auth_<method>.c, each basic auth-method has now
its own implementation-file
+ added -auth - flag:
- list - lists all available methods
- none - no auth, like -nolock
- passwd - standard login, possible shadowsupport
- pam - use pam for authentification
- md5:hash - provide a md5-hash for authentification
* support for 'shadow'-passwords is part of the passwd authmodule
2005-05-06:

9
README
View file

@ -59,22 +59,25 @@
3. usage
--------
aklock [-vh] [-blank]
aklock [-vh] [-blank] [-cursor <theme|xcursor:file>]
[-auth list|<none|passwd|pam|md5:pwdhash>]
-h displays a little help
-v displays version number
-blank hides the content of the screen with a big, black area
-cursor choose between multiple cursors
-auth choose between different authmethods.
after locking 'aklock' will show a modified mousecursor. you have to
enter your password blindly. if its the correct password the screen will
unlock
unlock.
4. todo
-------
- better documentation, updated manpage
- check on irix, sun, hp etc etc
- users wants to specify lockcursor + background for -blank
5. author
---------

View file

@ -18,8 +18,10 @@ Default(aklock_target)
aklock_options = Options(aklock_optfile)
aklock_options.AddOptions(
BoolOption('debug', 'build debug version', 0),
BoolOption('passwd', 'support for classic passwd', 0),
BoolOption('shadow', 'support for shadowpasswords', 0),
BoolOption('pam', 'support for pam', 1),
BoolOption('md5', 'support for md5', 1),
BoolOption('xcursor', 'support xcursor-themes', 1),
@ -45,7 +47,7 @@ aklock_env.AppendUnique(
CPPFLAGS = [ '-Wall' ],
CPPPATH = [ '/usr/X11R6/include' ],
LIBPATH = ['/usr/X11R6/lib'],
LIBS = [ 'X11', 'crypt' ])
LIBS = [ 'X11' ])
if aklock_env['debug']:
aklock_env.AppendUnique(
@ -53,10 +55,15 @@ if aklock_env['debug']:
LINKFLAGS = [ '-g' ],
CPPFLAGS = [ '-g' ])
if aklock_env['passwd']:
aklock_env.AppendUnique(
CPPDEFINES = [ 'PASSWD_PWD' ],
LIBS = [ 'crypt' ])
if aklock_env['pam']:
aklock_env.AppendUnique(
CPPDEFINES = [ 'PAM_PWD' ],
LIBS = [ 'pam' ])
LIBS = [ 'pam', 'crypt' ])
if sys.platform == 'linux2' or sys.platform == 'linux-i386':
aklock_env.AppendUnique(LIBS = ['pam_misc'])
@ -66,6 +73,10 @@ if aklock_env['shadow']:
aklock_env.AppendUnique(
CPPDEFINES = [ 'SHADOW_PWD' ])
if aklock_env['md5']:
aklock_env.AppendUnique(
CPPDEFINES = [ 'MD5_PWD' ])
if aklock_env['xcursor']:
conf = aklock_env.Configure()
if conf.CheckLib('Xcursor', 'XcursorSupportsARGB', 1):

View file

@ -5,12 +5,19 @@
#
##########################################################
aklock_sources = [ 'aklock.c', 'akcursors.c' ]
aklock_sources = [ 'aklock.c', 'akcursors.c', 'auth_none.c' ]
Import('aklock_env')
build = aklock_env.Copy()
if build['passwd']:
aklock_sources += [ 'auth_passwd.c' ]
if build['md5']:
aklock_sources += [ 'auth_md5.c' ]
if build['pam']:
aklock_sources += [ 'auth_pam.c' ]
aklock = build.Program('aklock', aklock_sources)
build.AddPostAction(aklock, Chmod(aklock, 0755))

View file

@ -40,33 +40,25 @@
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <pwd.h>
#include <grp.h>
#include <limits.h>
#include <string.h>
#include <unistd.h>
#include <math.h>
#include <ctype.h>
#ifdef SHADOW_PWD
# include <shadow.h>
#endif /* SHADOW_PWD */
#ifdef PAM_PWD
# include <security/pam_appl.h>
# ifdef LINUX
# include <security/pam_misc.h>
# endif
#endif /* PAM_PWD */
/*----------------------------------------------*\
\*----------------------------------------------*/
#include "aklock.h"
struct akXInfo {
Display* display;
Window root;
Window window;
Colormap colormap;
Cursor cursor;
int width;
int height;
};
/*------------------------------------------------------------------*\
globals
\*------------------------------------------------------------------*/
@ -82,186 +74,34 @@
# define DBGMSG
#endif // DEBUG
struct passwd *pw;
static struct akAuth* ak_authmodules[] = {
&aklock_auth_none,
#ifdef MD5_PWD
&aklock_auth_md5,
#endif /* MD5_PWD */
#ifdef PASSWD_PWD
&aklock_auth_passwd,
#endif /* PASSWD_PWD */
#ifdef PAM_PWD
&aklock_auth_pam,
#endif
NULL
};
/*------------------------------------------------------------------*\
\*------------------------------------------------------------------*/
void displayUsage() {
printf("\naklock [-h] [-v] [-blank] [-nolock] [-cursor <theme|xcursor:file>]\n");
printf("\naklock [-h] [-v] [-blank] [-cursor <theme|xcursor:file>]\n");
printf(" [-auth list|<none|passwd|pam|md5:pwdhash>]\n");
}
/*------------------------------------------------------------------*\
pam-related stuff
taken from pure-ftpd's authstuff, but you can see similar stuff
in xlockmore, openssh and basicly all pam-related apps :)
\*------------------------------------------------------------------*/
#ifdef PAM_PWD
# define PAM_YN { \
if (PAM_error != 0 || pam_error != PAM_SUCCESS) { \
fprintf(stderr, "pam error:%s\n", pam_strerror(pam_handle, pam_error)); \
pam_end(pam_handle, pam_error); \
PAM_username = NULL; \
PAM_password = NULL; \
return 0;\
} \
}
# define GET_MEM \
size += sizeof(struct pam_response); \
if ((reply = realloc(reply, size)) == NULL) { \
PAM_error = 1; \
return PAM_CONV_ERR; \
}
static const char* PAM_username = NULL;
static const char* PAM_password = NULL;
static int PAM_error = 0;
static int pam_error = PAM_SUCCESS;
static int PAM_conv(int num_msg, const struct pam_message **msgs,
struct pam_response **resp, void *appdata_ptr) {
int count = 0;
unsigned int replies = 0U;
struct pam_response *reply = NULL;
size_t size = (size_t) 0U;
(void) appdata_ptr;
*resp = NULL;
for (count = 0; count < num_msg; count++) {
switch (msgs[count]->msg_style) {
case PAM_PROMPT_ECHO_ON:
GET_MEM;
memset(&reply[replies], 0, sizeof reply[replies]);
if ((reply[replies].resp = strdup(PAM_username)) == NULL) {
# ifdef PAM_BUF_ERR
reply[replies].resp_retcode = PAM_BUF_ERR;
# endif
PAM_error = 1;
return PAM_CONV_ERR;
}
reply[replies++].resp_retcode = PAM_SUCCESS;
/* PAM frees resp */
break;
case PAM_PROMPT_ECHO_OFF:
GET_MEM;
memset(&reply[replies], 0, sizeof reply[replies]);
if ((reply[replies].resp = strdup(PAM_password)) == NULL) {
# ifdef PAM_BUF_ERR
reply[replies].resp_retcode = PAM_BUF_ERR;
# endif
PAM_error = 1;
return PAM_CONV_ERR;
}
reply[replies++].resp_retcode = PAM_SUCCESS;
/* PAM frees resp */
break;
case PAM_TEXT_INFO:
/* ignore it... */
break;
case PAM_ERROR_MSG:
default:
/* Must be an error of some sort... */
free(reply);
PAM_error = 1;
return PAM_CONV_ERR;
}
}
*resp = reply;
return PAM_SUCCESS;
}
static struct pam_conv PAM_conversation = {
&PAM_conv, NULL
};
#endif /* PAM_PWD */
/*------------------------------------------------------------------*\
\*------------------------------------------------------------------*/
int passwordOk(const char *s) {
#if 0
char key[3];
char *encr;
key[0] = *(pw->pw_passwd);
key[1] = (pw->pw_passwd)[1];
key[2] = 0;
encr = crypt(s, key);
return !strcmp(encr, pw->pw_passwd);
#else
/* simpler, and should work with crypt() algorithms using longer
salt strings (like the md5-based one on freebsd). --marekm */
#ifdef PAM_PWD
pam_handle_t* pam_handle = NULL;
PAM_username = pw->pw_name;
PAM_password = s;
pam_error = pam_start("login", PAM_username, &PAM_conversation, &pam_handle);
PAM_YN;
pam_error = pam_authenticate(pam_handle, 0);
PAM_YN;
pam_error = pam_end(pam_handle, pam_error);
PAM_YN;
return 1;
#else
return !strcmp(crypt(s, pw->pw_passwd), pw->pw_passwd);
#endif /* PAM_PWD */
#endif /* 0 */
}
/*------------------------------------------------------------------*\
check if the system would be able to authentificate the user
\*------------------------------------------------------------------*/
void checkAuth() {
#ifdef SHADOW_PWD
struct spwd *sp;
#endif
errno = 0;
pw = getpwuid(getuid());
if (!pw) {
perror("password entry for uid not found");
exit(1);
}
#ifdef SHADOW_PWD
sp = getspnam(pw->pw_name);
if (sp)
pw->pw_passwd = sp->sp_pwdp;
endspent();
#endif
/* we can be installed setuid root to support shadow passwords,
and we don't need root privileges any longer. --marekm */
setuid(getuid());
#ifndef PAM_PWD
if (strlen(pw->pw_passwd) < 13) {
perror("aklock: password entry has no pwd\n");
exit(1);
}
#endif /* PAM_PWD */
}
/*------------------------------------------------------------------*\
\*------------------------------------------------------------------*/
/*------------------------------------------------------------------*\
\*------------------------------------------------------------------*/
void initOpts(struct akOpts* opts) {
opts->dont_lock = 0;
opts->auth = ak_authmodules[0];
opts->use_blank = 0;
opts->cursor_name = "mini";
@ -376,13 +216,47 @@ int main(int argc, char **argv) {
initOpts(&opts);
// parse options
/* parse options */
if (argc != 1) {
for(arg = 1; arg <= argc; arg++) {
if (!strcmp(argv[arg - 1], "-blank")) {
opts.use_blank = 1;
} else if (!strcmp(argv[arg - 1], "-nolock")) {
opts.dont_lock = 1;
} else if (!strcmp(argv[arg - 1], "-auth")) {
if (arg < argc) {
char* char_tmp;
struct akAuth* auth_tmp = NULL;
struct akAuth** i;
if (!strcmp(argv[arg], "list")) {
for(i = ak_authmodules; *i; ++i) {
printf("%s\n", (*i)->name);
}
exit(0);
}
for(i = ak_authmodules; *i; ++i) {
char_tmp = strstr(argv[arg], (*i)->name);
if(char_tmp && char_tmp == argv[arg]) {
auth_tmp = (*i);
if (!auth_tmp->init(argv[arg])) {
fprintf(stderr, "aklock: error, failed init of [%s].\n", auth_tmp->name);
exit(1);
}
opts.auth = auth_tmp;
break;
}
}
if (!auth_tmp) {
fprintf(stderr, "aklock: error, couldnt find the auth module you specified.\n");
exit(1);
}
} else {
fprintf(stderr, "aklock, error, missing argument\n");
displayUsage();
exit(1);
}
} else if (!strcmp(argv[arg - 1], "-cursor")) {
if (arg < argc)
opts.cursor_name = argv[arg];
@ -401,12 +275,8 @@ int main(int argc, char **argv) {
}
}
if (!opts.dont_lock)
checkAuth();
initXInfo(&xinfo, &opts);
/* create the windows */
xswa.override_redirect = True;
xsmask |= CWOverrideRedirect;
@ -434,7 +304,7 @@ int main(int argc, char **argv) {
XRaiseWindow(xinfo.display, xinfo.window);
/* TODO: -bg <blank|transparent|shaded> */
if (opts.use_blank) {
/* if (opts.use_blank) {
XImage* ximage;
ximage = XGetImage (xinfo.display, xinfo.root, 0, 0,
@ -456,7 +326,7 @@ int main(int argc, char **argv) {
XDestroyImage(ximage);
XFreeGC(xinfo.display, gc);
}
}
} */
/* try to grab 2 times, another process (windowmanager) may have grabbed
* the keyboard already */
if ((XGrabKeyboard(xinfo.display, xinfo.window, True, GrabModeAsync, GrabModeAsync,
@ -482,9 +352,6 @@ int main(int argc, char **argv) {
switch (ev.type) {
case KeyPress:
if (opts.dont_lock)
goto exit;
if (ev.xkey.time < timeout) {
XBell(xinfo.display, 0);
break;
@ -507,7 +374,7 @@ int main(int argc, char **argv) {
break;
rbuf[rlen] = 0;
if (passwordOk(rbuf))
if (opts.auth->auth(rbuf))
goto exit;
XSync(xinfo.display, True); /* discard pending events to start really fresh */
@ -538,6 +405,9 @@ int main(int argc, char **argv) {
}
exit:
opts.auth->deinit();
XDestroyWindow(xinfo.display, xinfo.window);
XFreeCursor(xinfo.display, xinfo.cursor);
XCloseDisplay(xinfo.display);

View file

@ -22,6 +22,13 @@
/* ---------------------------------------------------------------- *\
\* ---------------------------------------------------------------- */
struct akAuth {
const char* name;
int (*init)(const char* args);
int (*auth)(const char* pass);
int (*deinit)();
};
struct akCursor {
const char* name;
unsigned int width;
@ -33,22 +40,11 @@ struct akCursor {
unsigned char* mask;
};
struct akXInfo {
Display* display;
Window root;
Window window;
Colormap colormap;
Cursor cursor;
int width;
int height;
};
struct akOpts {
char dont_lock;
struct akAuth* auth;
char use_blank;
char* cursor_name;
@ -62,6 +58,19 @@ struct akOpts {
\*------------------------------------------------------------------*/
extern struct akCursor ak_cursors[];
/*------------------------------------------------------------------*\
\*------------------------------------------------------------------*/
extern struct akAuth aklock_auth_none;
#ifdef MD5_PWD
extern struct akAuth aklock_auth_md5;
#endif /* MD5_PWD */
#ifdef PASSWD_PWD
extern struct akAuth aklock_auth_passwd;
#endif /* PASSWD_PWD */
#ifdef PAM_PWD
extern struct akAuth aklock_auth_pam;
#endif /* PAM_PWD */
/* ---------------------------------------------------------------- *\
\* ---------------------------------------------------------------- */
#endif // _AKLOCK_H_

396
src/auth_md5.c Normal file
View file

@ -0,0 +1,396 @@
/* ---------------------------------------------------------------- *\
file : auth_md5.c
author : m. gumz <akira at fluxbox dot org>
copyr : copyright (c) 2005 by m. gumz
license : based on:
MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
start : Sa 07 Mai 2005 13:21:45 CEST
\* ---------------------------------------------------------------- */
/* ---------------------------------------------------------------- *\
about :
\* ---------------------------------------------------------------- */
/* ---------------------------------------------------------------- *\
includes
\* ---------------------------------------------------------------- */
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "aklock.h"
/*------------------------------------------------------------------*\
\*------------------------------------------------------------------*/
enum {
S11 = 7,
S12 = 12,
S13 = 17,
S14 = 22,
S21 = 5,
S22 = 9,
S23 = 14,
S24 = 20,
S31 = 4,
S32 = 11,
S33 = 16,
S34 = 23,
S41 = 6,
S42 = 10,
S43 = 15,
S44 = 21
};
typedef struct {
unsigned long int state[4]; /* state (ABCD) */
unsigned long int count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} md5Context;
static void md5_transform(unsigned long int[4], unsigned char [64]);
static void md5_encode(unsigned char*, unsigned long int*, unsigned int);
static void md5_decode(unsigned long int*, unsigned char*, unsigned int);
static void md5_init(md5Context*);
static void md5_update(md5Context*, unsigned char *, unsigned int);
static void md5_final(unsigned char[16], md5Context *);
/*------------------------------------------------------------------*\
\*------------------------------------------------------------------*/
static unsigned char padding[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* F, G, H and I are basic MD5 functions. */
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits. */
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/*--------------------------------------------------------*\
FF, GG, HH, and II transformations for rounds 1, 2, 3,
and 4. Rotation is separate from addition to prevent
recomputation.
\*--------------------------------------------------------*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (unsigned long int)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (unsigned long int)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (unsigned long int)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (unsigned long int)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
/*------------------------------------------------------------------*\
\*------------------------------------------------------------------*/
/*--------------------------------------------------------*\
MD5 initialization. Begins an MD5 operation, writing
a new context.
\*--------------------------------------------------------*/
static void md5_init(md5Context* context) {
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants.*/
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
/*--------------------------------------------------------*\
MD5 block update operation. Continues an MD5
message-digest operation, processing another message
block, and updating the context.
\*--------------------------------------------------------*/
static void md5_update(md5Context* context, unsigned char* input, unsigned int inputLen) {
unsigned int i, index, partLen;
/* Compute number of bytes mod 64 */
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((context->count[0] += ((unsigned long int)inputLen << 3)) < ((unsigned long int)inputLen << 3))
context->count[1]++;
context->count[1] += ((unsigned long int)inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible. */
if (inputLen >= partLen) {
memcpy((unsigned char*)&context->buffer[index],
(unsigned char*)input,
partLen);
md5_transform(context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
md5_transform(context->state, &input[i]);
index = 0;
}
else
i = 0;
/* Buffer remaining input */
memcpy((unsigned char*)&context->buffer[index],
(unsigned char*)&input[i],
inputLen-i);
}
/*--------------------------------------------------------*\
MD5 finalization. Ends an MD5 message-digest operation,
writing the the message digest and zeroizing the context.
\*--------------------------------------------------------*/
static void md5_final(unsigned char digest[16], md5Context* context) {
unsigned char bits[8];
unsigned int index;
unsigned int padLen;
/* Save number of bits */
md5_encode(bits, context->count, 8);
/* Pad out to 56 mod 64. */
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
md5_update(context, padding, padLen);
/* Append length (before padding) */
md5_update(context, bits, 8);
/* Store state in digest */
md5_encode(digest, context->state, 16);
/* Zeroize sensitive information. */
memset((unsigned char*)context, 0, sizeof (*context));
}
/* MD5 basic transformation. Transforms state based on block.
*/
static void md5_transform(unsigned long int state[4], unsigned char block[64]) {
unsigned long int a = state[0];
unsigned long int b = state[1];
unsigned long int c = state[2];
unsigned long int d = state[3];
unsigned long int x[16];
md5_decode(x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information. */
memset((unsigned char*)x, 0, sizeof (x));
}
/*--------------------------------------------------------*\
Encodes input into output. Assumes len is a multiple
of 4.
\*--------------------------------------------------------*/
static void md5_encode(unsigned char* output, unsigned long int* input, unsigned int len) {
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}
/*--------------------------------------------------------*\
Decodes input into output. Assumes len is a multiple
of 4.
\*--------------------------------------------------------*/
static void md5_decode(unsigned long int* output, unsigned char* input, unsigned int len) {
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((unsigned long int)input[j]) |
(((unsigned long int)input[j+1]) << 8) |
(((unsigned long int)input[j+2]) << 16) |
(((unsigned long int)input[j+3]) << 24);
}
/* ---------------------------------------------------------------- *\
\* ---------------------------------------------------------------- */
static const char* userhash = NULL;
static int init(const char* args) {
if (args) {
char* check = strstr(args, "md5:");
if (!check || check != args) {
fprintf(stderr, "aklock: error, missing arguments for [md5].\n");
return 0;
}
if (strlen(&args[4]) != 32) {
fprintf(stderr, "aklock: error, invalid md5-hash.\n");
return 0;
}
userhash = &args[4];
return 1;
}
return 0;
}
static int deinit() {
return 1;
}
static int auth(const char* pass) {
unsigned char tmpdigest[16];
unsigned char digest[32];
unsigned int i;
md5Context md5;
if (!pass || !userhash)
return 0;
md5_init(&md5);
md5_update(&md5, (unsigned char*)pass, strlen(pass));
md5_final(tmpdigest, &md5);
for (i = 0; i < 16; i++) {
sprintf(&digest[i*2], "%02x", tmpdigest[i]);
}
return !strcmp(digest, userhash);
}
struct akAuth aklock_auth_md5 = {
"md5",
init,
auth,
deinit
};
/* ---------------------------------------------------------------- *\
\* ---------------------------------------------------------------- */

47
src/auth_none.c Normal file
View file

@ -0,0 +1,47 @@
/* ---------------------------------------------------------------- *\
file : auth_none.c
author : m. gumz <akira at fluxbox dot org>
copyr : copyright (c) 2005 by m. gumz
license : see LICENSE
start : Sa 07 Mai 2005 16:41:28 CEST
\* ---------------------------------------------------------------- */
/* ---------------------------------------------------------------- *\
about : this authmodule does absolutly nothing :)
\* ---------------------------------------------------------------- */
/* ---------------------------------------------------------------- *\
includes
\* ---------------------------------------------------------------- */
#include "aklock.h"
/* ---------------------------------------------------------------- *\
\* ---------------------------------------------------------------- */
static int init(const unsigned char* args) {
return 1;
}
static int deinit() {
return 1;
}
static int auth(const unsigned char* passwd) {
return 1;
}
struct akAuth aklock_auth_none = {
"none",
init,
deinit,
auth
};
/* ---------------------------------------------------------------- *\
\* ---------------------------------------------------------------- */

181
src/auth_pam.c Normal file
View file

@ -0,0 +1,181 @@
/* ---------------------------------------------------------------- *\
file : auth_pam.c
author : m. gumz <akira at fluxbox dot org>
copyr : copyright (c) 2005 by m. gumz
license : see LICENSE
start : Sa 07 Mai 2005 16:21:24 CEST
\* ---------------------------------------------------------------- */
/* ---------------------------------------------------------------- *\
about :
pam-authentification for aklock
taken from pure-ftpd's authstuff, but you can see similar stuff
in xlockmore, openssh and basicly all pam-related apps :)
\* ---------------------------------------------------------------- */
/* ---------------------------------------------------------------- *\
includes
\* ---------------------------------------------------------------- */
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
#include <security/pam_appl.h>
#ifdef LINUX
# include <security/pam_misc.h>
#endif /* LINUX */
#include "aklock.h"
/* ---------------------------------------------------------------- *\
\* ---------------------------------------------------------------- */
#define PAM_YN { \
if (PAM_error != 0 || pam_error != PAM_SUCCESS) { \
fprintf(stderr, "pam error:%s\n", pam_strerror(pam_handle, pam_error)); \
pam_end(pam_handle, pam_error); \
PAM_username = NULL; \
PAM_password = NULL; \
return 0;\
} \
}
#define GET_MEM \
size += sizeof(struct pam_response); \
if ((reply = realloc(reply, size)) == NULL) { \
PAM_error = 1; \
return PAM_CONV_ERR; \
}
static const char* PAM_username = NULL;
static const char* PAM_password = NULL;
static int PAM_error = 0;
static int pam_error = PAM_SUCCESS;
static int PAM_conv(int num_msg, const struct pam_message **msgs,
struct pam_response **resp, void *appdata_ptr) {
int count = 0;
unsigned int replies = 0U;
struct pam_response *reply = NULL;
size_t size = (size_t) 0U;
(void) appdata_ptr;
*resp = NULL;
for (count = 0; count < num_msg; count++) {
switch (msgs[count]->msg_style) {
case PAM_PROMPT_ECHO_ON:
GET_MEM;
memset(&reply[replies], 0, sizeof reply[replies]);
if ((reply[replies].resp = strdup(PAM_username)) == NULL) {
#ifdef PAM_BUF_ERR
reply[replies].resp_retcode = PAM_BUF_ERR;
#endif
PAM_error = 1;
return PAM_CONV_ERR;
}
reply[replies++].resp_retcode = PAM_SUCCESS;
/* PAM frees resp */
break;
case PAM_PROMPT_ECHO_OFF:
GET_MEM;
memset(&reply[replies], 0, sizeof reply[replies]);
if ((reply[replies].resp = strdup(PAM_password)) == NULL) {
# ifdef PAM_BUF_ERR
reply[replies].resp_retcode = PAM_BUF_ERR;
# endif
PAM_error = 1;
return PAM_CONV_ERR;
}
reply[replies++].resp_retcode = PAM_SUCCESS;
/* PAM frees resp */
break;
case PAM_TEXT_INFO:
/* ignore it... */
break;
case PAM_ERROR_MSG:
default:
/* Must be an error of some sort... */
free(reply);
PAM_error = 1;
return PAM_CONV_ERR;
}
}
*resp = reply;
return PAM_SUCCESS;
}
static struct pam_conv PAM_conversation = {
&PAM_conv, NULL
};
/*------------------------------------------------------------------*\
\*------------------------------------------------------------------*/
static struct passwd* pwd_entry = NULL;
static int init(const char* args) {
errno = 0;
pwd_entry = getpwuid(getuid());
if (!pwd_entry) {
perror("password entry for uid not found");
return 0;
}
/* we can be installed setuid root to support shadow passwords,
and we don't need root privileges any longer. --marekm */
setuid(getuid());
return 1;
}
static int deinit() {
pwd_entry = NULL;
return 0;
}
static int auth(const char* pass) {
pam_handle_t* pam_handle = NULL;
if (!pass || !pwd_entry)
return 0;
PAM_username = pwd_entry->pw_name;
PAM_password = pass;
pam_error = pam_start("login", PAM_username, &PAM_conversation, &pam_handle);
PAM_YN;
pam_error = pam_authenticate(pam_handle, 0);
PAM_YN;
pam_error = pam_end(pam_handle, pam_error);
PAM_YN;
return 1;
}
struct akAuth aklock_auth_pam = {
"pam",
init,
auth,
deinit
};
/* ---------------------------------------------------------------- *\
\* ---------------------------------------------------------------- */

111
src/auth_passwd.c Normal file
View file

@ -0,0 +1,111 @@
/* ---------------------------------------------------------------- *\
file : auth_passwd.c
author : m. gumz <akira at fluxbox dot org>
copyr : copyright (c) 2005 by m. gumz
license : see LICENSE
start : Sa 07 Mai 2005 16:40:01 CEST
\* ---------------------------------------------------------------- */
/* ---------------------------------------------------------------- *\
about :
\* ---------------------------------------------------------------- */
/* ---------------------------------------------------------------- *\
includes
\* ---------------------------------------------------------------- */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <pwd.h>
#include <grp.h>
#include <limits.h>
#include <string.h>
#include <unistd.h>
#ifdef SHADOW_PWD
# include <shadow.h>
#endif /* SHADOW_PWD */
#include "aklock.h"
/* ---------------------------------------------------------------- *\
\* ---------------------------------------------------------------- */
static struct passwd* pwd_entry = NULL;
static int init(const char* args) {
#ifdef SHADOW_PWD
struct spwd* sp = NULL;
#endif
errno = 0;
pwd_entry = getpwuid(getuid());
if (!pwd_entry) {
perror("password entry for uid not found");
return 0;
}
#ifdef SHADOW_PWD
sp = getspnam(pwd_entry->pw_name);
if (sp)
pwd_entry->pw_passwd = sp->sp_pwdp;
endspent();
#endif
/* we can be installed setuid root to support shadow passwords,
and we don't need root privileges any longer. --marekm */
setuid(getuid());
if (strlen(pwd_entry->pw_passwd) < 13) {
perror("password entry has no pwd\n");
return 0;
}
return 1;
}
static int deinit() {
return 1;
}
static int auth(const char* pass) {
#if 0
char key[3];
char *encr;
if (!pass || !pwd_entry)
return 0;
key[0] = *(pwd_entry->pw_passwd);
key[1] = (pwd_entry->pw_passwd)[1];
key[2] = 0;
encr = crypt(pass, key);
return !strcmp(encr, pw->pw_passwd);
#else
if (!pass || !pwd_entry)
return 0;
/* simpler, and should work with crypt() algorithms using longer
salt strings (like the md5-based one on freebsd). --marekm */
return !strcmp(crypt(pass, pwd_entry->pw_passwd), pwd_entry->pw_passwd);
#endif /* 0 */
}
struct akAuth aklock_auth_passwd = {
"passwd",
init,
auth,
deinit
};
/* ---------------------------------------------------------------- *\
\* ---------------------------------------------------------------- */