diff options
Diffstat (limited to 'crypto/kerberosIV/lib/kclient/KClient.c')
-rw-r--r-- | crypto/kerberosIV/lib/kclient/KClient.c | 440 |
1 files changed, 440 insertions, 0 deletions
diff --git a/crypto/kerberosIV/lib/kclient/KClient.c b/crypto/kerberosIV/lib/kclient/KClient.c new file mode 100644 index 0000000..6d4ed60 --- /dev/null +++ b/crypto/kerberosIV/lib/kclient/KClient.c @@ -0,0 +1,440 @@ +/* + * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* KClient.c - KClient glue to krb4.dll + * Author: Jörgen Karlsson - d93-jka@nada.kth.se + * Date: June 1996 + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +RCSID("$Id: KClient.c,v 1.14 1999/12/02 16:58:40 joda Exp $"); +#endif + +#ifdef WIN32 /* Visual C++ 4.0 (Windows95/NT) */ +#include <Windows.h> +#endif /* WIN32 */ + +//#include <string.h> +#include <winsock.h> +#include "passwd_dlg.h" +#include "KClient.h" +#include "krb.h" + +char guser[64]; + +void +msg(char *text) +{ + HWND wnd = GetActiveWindow(); + MessageBox(wnd, text, "KClient message", MB_OK|MB_APPLMODAL); +} + +BOOL +SendTicketForService(LPSTR service, LPSTR version, int fd) +{ + KTEXT_ST ticket; + MSG_DAT mdat; + CREDENTIALS cred; + des_key_schedule schedule; + char name[SNAME_SZ], inst[INST_SZ], realm[REALM_SZ]; + int ret; + static KClientSessionInfo foo; + KClientKey key; + + kname_parse(name, inst, realm, service); + strlcpy(foo.realm, realm, sizeof(foo.realm)); + + if(KClientStatus(&foo) == KClientNotLoggedIn) + KClientLogin(&foo, &key); + + ret = krb_sendauth (0, fd, &ticket, + name, inst, realm, 17, &mdat, + &cred, &schedule, NULL, NULL, version); + if(ret) + return FALSE; + return TRUE; +} + +BOOL WINAPI +DllMain(HANDLE hInst, ULONG reason, LPVOID lpReserved) +{ + WORD wVersionRequested; + WSADATA wsaData; + int err; + + switch(reason){ + case DLL_PROCESS_ATTACH: + wVersionRequested = MAKEWORD(1, 1); + + err = WSAStartup(wVersionRequested, &wsaData); + + if (err != 0) + { + /* Tell the user that we couldn't find a useable */ + /* winsock.dll. */ + msg("Cannot find winsock.dll"); + return FALSE; + } + break; + case DLL_PROCESS_DETACH: + WSACleanup(); + } + + return TRUE; +} + +Kerr +KClientMessage(char *text, Kerr error) +{ + msg(text); + return error; +} + +/* KClientInitSession + * You need to call this routine before calling most other routines. + * It initializes a KClientSessionInfo structure. + * The local and remote addresses are for use in KClientEncrypt, + * KClientDecrypt, KClientMakeSendAuth and KClientVerifySendAuth. + * If you don't use any of these routines it's perfectly OK to do the following... + * err = KClientInitSession(session,0,0,0,0); + */ +Kerr +KClientInitSession(KClientSessionInfo *session, + unsigned long lAddr, + unsigned short lPort, + unsigned long fAddr, + unsigned short fPort) +{ + session->lAddr = lAddr; + session->lPort = lPort; + session->fAddr = fAddr; + session->fPort = fPort; + if(tf_get_pname(session->user) != KSUCCESS) + *(session->user) = '\0'; + if(tf_get_pinst(session->inst) != KSUCCESS) + *(session->inst) = '\0'; + krb_get_lrealm (session->realm, 1); + if(*(session->user)) + strlcpy(guser, session->user, sizeof(guser)); + else + *guser ='\0'; + + return 0; +} + + +/* KClientGetTicketForService + * This routine gets an authenticator to be passed to a service. + * If the user isn't already logged in the user is prompted for a password. + */ +Kerr +KClientGetTicketForService(KClientSessionInfo *session, + char *service, + void *buf, + unsigned long *buflen) +{ + CREDENTIALS c; + KClientKey k; + KTEXT_ST ticket; + char serv[255], inst[255], realm[255]; + Kerr err; + + // KClientSetUserName(session->user); + err = kname_parse(serv,inst,realm,service); + if(*realm) + strlcpy(session->realm, realm, sizeof(session->realm)); + else + strlcpy(realm, session->realm, sizeof(realm)); + if(KClientStatus(session) == KClientNotLoggedIn) + if((err = KClientLogin(session, &k)) != KSUCCESS) + return err; + + if((err = krb_mk_req(&ticket, serv, inst, realm, 0)) != KSUCCESS) + return KClientMessage(KClientErrorText(err,0),err); + if((err = krb_get_cred(serv, inst, realm, &c)) != KSUCCESS) + return KClientMessage(KClientErrorText(err,0),err); + + if(*buflen >= ticket.length) + { + *buflen = ticket.length + sizeof(unsigned long); + CopyMemory(buf, &ticket, *buflen); + CopyMemory(session->key, c.session, sizeof(session->key)); + } + else + err = -1; + return err; +} + + +/* KClientLogin + * This routine "logs in" by getting a ticket granting ticket from kerberos. + * It returns the user's private key which can be used to automate login at + * a later time with KClientKeyLogin. + */ + +Kerr +KClientLogin(KClientSessionInfo *session, + KClientKey *privateKey) +{ + CREDENTIALS c; + Kerr err; + char passwd[100]; + + if((err = pwd_dialog(guser, passwd))) + return err; + if(KClientStatus(session) == KClientNotLoggedIn) + { + + if((err = krb_get_pw_in_tkt(guser, session->inst, session->realm, + "krbtgt", session->realm, + DEFAULT_TKT_LIFE, passwd)) != KSUCCESS) + return KClientMessage(KClientErrorText(err,0),err); + } + if((err = krb_get_cred("krbtgt", session->realm, + session->realm, &c)) == KSUCCESS) + CopyMemory(privateKey, c.session, sizeof(*privateKey)); + return err; +} + + +/* KClientPasswordLogin + * This routine is similiar to KClientLogin but instead of prompting the user + * for a password it uses the password supplied to establish login. + */ +Kerr +KClientPasswordLogin(KClientSessionInfo *session, + char *password, + KClientKey *privateKey) +{ + return krb_get_pw_in_tkt(guser, session->inst, session->realm, + "krbtgt", + session->realm, + DEFAULT_TKT_LIFE, + password); +} + + +static key_proc_t +key_proc(void *arg) +{ + return arg; +} + +/* KClientKeyLogin + * This routine is similiar to KClientLogin but instead of prompting the user + * for a password it uses the private key supplied to establish login. + */ +Kerr +KClientKeyLogin(KClientSessionInfo *session, + KClientKey *privateKey) +{ + return krb_get_in_tkt(guser, session->inst, session->realm, + "krbtgt", + session->realm, + DEFAULT_TKT_LIFE, + key_proc, + 0, + privateKey); +} + +/* KClientLogout + * This routine destroys all credentials stored in the credential cache + * effectively logging the user out. + */ +Kerr +KClientLogout(void) +{ + return 0; +} + + +/* KClientStatus + * This routine returns the user's login status which can be + * KClientLoggedIn or KClientNotLoggedIn. + */ +short +KClientStatus(KClientSessionInfo *session) +{ + CREDENTIALS c; + if(krb_get_cred("krbtgt", + session->realm, + session->realm, &c) == KSUCCESS) + return KClientLoggedIn; + else + return KClientNotLoggedIn; +} + + +/* KClientGetUserName + * This routine returns the name the user supplied in the login dialog. + * No name is returned if the user is not logged in. + */ +Kerr +KClientGetUserName(char *user) +{ + strcpy(user, guser); + return 0; +} + + +/* KClientSetUserName + * This routine sets the name that will come up in the login dialog + * the next time the user is prompted for a password. + */ +Kerr +KClientSetUserName(char *user) +{ + strlcpy(guser, user, sizeof(guser)); + return 0; +} + + +/* KClientCacheInitialTicket + * This routine is used to obtain a ticket for the password changing service. + */ +Kerr +KClientCacheInitialTicket(KClientSessionInfo *session, + char *service) +{ + return 0; +} + + +/* KClientGetSessionKey + * This routine can be used to obtain the session key which is stored + * in the KClientSessionInfo record. The session key has no usefullness + * with any KClient calls but it can be used to with the MIT kerberos API. + */ +Kerr +KClientGetSessionKey(KClientSessionInfo *session, + KClientKey *sessionKey) +{ + CopyMemory(sessionKey, session->key, sizeof(*sessionKey)); + return 0; +} + + +/* KClientMakeSendAuth + * This routine is used to create an authenticator that is the same as those + * created by the kerberos routine SendAuth. + */ +Kerr +KClientMakeSendAuth(KClientSessionInfo *session, + char *service, + void *buf, + unsigned long *buflen, + long checksum, + char *applicationVersion) +{ + return 0; +} + + +/* KClientVerifySendAuth + * This routine is used to verify a response made by a server doing RecvAuth. + * The two routines KClientMakeSendAuth and KClientVerifySendAuth together + * provide the functionality of SendAuth minus the transmission of authenticators + * between client->server->client. + */ +Kerr +KClientVerifySendAuth(KClientSessionInfo *session, + void *buf, + unsigned long *buflen) +{ + return 0; +} + + +/* KClientEncrypt + * This routine encrypts a series a bytes for transmission to the remote host. + * For this to work properly you must be logged in and you must have specified + * the remote and local addresses in KClientInitSession. The unencrypted + * message pointed to by buf and of length buflen is returned encrypted + * in encryptBuf of length encryptLength. + * The encrypted buffer must be at least 26 bytes longer the buf. + */ +Kerr +KClientEncrypt(KClientSessionInfo *session, + void *buf, + unsigned long buflen, + void *encryptBuf, + unsigned long *encryptLength) +{ + int num = 64; + des_cfb64_encrypt(buf, encryptBuf, buflen, + (struct des_ks_struct*) session->key, + 0, &num, 1); + return 0; +} + + +/* KClientDecrypt + * This routine decrypts a series of bytes received from the remote host. + + * NOTE: this routine will not reverse a KClientEncrypt call. + * It can only decrypt messages sent from the remote host. + + * Instead of copying the decrypted message to an out buffer, + * the message is decrypted in place and you are returned + * an offset into the buffer where the decrypted message begins. + */ +Kerr +KClientDecrypt(KClientSessionInfo *session, + void *buf, + unsigned long buflen, + unsigned long *decryptOffset, + unsigned long *decryptLength) +{ + int num; + des_cfb64_encrypt(buf, buf, buflen, + (struct des_ks_struct*)session->key, 0, &num, 0); + *decryptOffset = 0; + *decryptLength = buflen; + return 0; +} + + +/* KClientErrorText + * This routine returns a text description of errors returned by any of + * the calls in this library. + */ +char * +KClientErrorText(Kerr err, + char *text) +{ + char *t = krb_get_err_text(err); + if(text) + strcpy(text, t); + return t; +} |