2
* $Id: uams_pgp.c,v 1.7.2.1 2003/01/26 16:55:05 srittau Exp $
4
* Copyright (c) 1990,1993 Regents of The University of Michigan.
5
* Copyright (c) 1999 Adrian Sun (asun@u.washington.edu)
6
* All Rights Reserved. See COPYRIGHT.
11
#endif /* HAVE_CONFIG_H */
22
#endif /* HAVE_UNISTD_H */
24
#include <atalk/logger.h>
27
#include <openssl/bn.h>
28
#include <openssl/dh.h>
29
#include <openssl/cast.h>
30
#else /* OPENSSL_DHX */
34
#endif /* OPENSSL_DHX */
36
#include <atalk/afp.h>
37
#include <atalk/uam.h>
41
#define CRYPTBUFLEN (KEYSIZE*2)
42
#define CRYPT2BUFLEN (KEYSIZE + PASSWDLEN)
44
/* hash a number to a 16-bit quantity */
45
#define pgphash(a) ((((unsigned long) (a) >> 8) ^ \
46
(unsigned long) (a)) & 0xffff)
49
static struct passwd *pgppwd;
50
static CAST_KEY castkey;
51
static u_int8_t randbuf[16];
54
static int pgp_login(void *obj, struct passwd **uam_pwd,
55
char *ibuf, int ibuflen,
56
char *rbuf, int *rbuflen)
58
BIGNUM *bn, *gbn, *pbn;
65
if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, (void *) &name, &i) < 0)
68
len = (unsigned char) *ibuf++;
70
return( AFPERR_PARAM );
73
memcpy(name, ibuf, len );
76
if ((unsigned long) ibuf & 1) /* padding */
79
if (( pgppwd = uam_getname(name, i)) == NULL ) {
83
LOG(log_info, logtype_uams, "pgp login: %s", name);
84
if (uam_checkuser(pgppwd) < 0)
85
return AFPERR_NOTAUTH;
87
/* get the challenge */
88
len = (unsigned char) *ibuf++;
91
/* get the signature. it's always 16 bytes. */
92
if (uam_afpserver_option(obj, UAM_OPTION_SIGNATURE,
93
(void *) &name, NULL) < 0) {
97
memcpy(rbuf + KEYSIZE, name, KEYSIZE);
103
static int pgp_logincont(void *obj, struct passwd **uam_pwd,
104
char *ibuf, int ibuflen,
105
char *rbuf, int *rbuflen)
107
unsigned char iv[] = "RJscorat";
108
BIGNUM *bn1, *bn2, *bn3;
114
/* check for session id */
115
memcpy(&sessid, ibuf, sizeof(sessid));
116
if (sessid != pgphash(obj))
118
ibuf += sizeof(sessid);
120
/* use rbuf as scratch space */
121
CAST_cbc_encrypt(ibuf, rbuf, CRYPT2BUFLEN, &castkey,
124
/* check to make sure that the random number is the same. we
125
* get sent back an incremented random number. */
126
if (!(bn1 = BN_bin2bn(rbuf, KEYSIZE, NULL)))
129
if (!(bn2 = BN_bin2bn(randbuf, sizeof(randbuf), NULL))) {
134
/* zero out the random number */
135
memset(rbuf, 0, sizeof(randbuf));
136
memset(randbuf, 0, sizeof(randbuf));
139
if (!(bn3 = BN_new())) {
145
BN_sub(bn3, bn1, bn2);
149
/* okay. is it one more? */
150
if (!BN_is_one(bn3)) {
157
if ( kcheckuser(*uam_pwd, rbuf) == 0) {
163
rbuf[PASSWDLEN] = '\0';
164
p = crypt( rbuf, pgppwd->pw_passwd );
165
memset(rbuf, 0, PASSWDLEN);
166
if ( strcmp( p, pgppwd->pw_passwd ) == 0 ) {
171
return AFPERR_NOTAUTH;
175
static int uam_setup(const char *path)
177
if (uam_register(UAM_SERVER_LOGIN, path, "PGPuam 1.0",
178
pgp_login, pgp_logincont, NULL) < 0)
184
static void uam_cleanup(void)
186
uam_unregister(UAM_SERVER_LOGIN, "PGPuam 1.0");
189
UAM_MODULE_EXPORT struct uam_export uams_pgp = {
192
uam_setup, uam_cleanup