~ubuntu-branches/ubuntu/precise/netatalk/precise

« back to all changes in this revision

Viewing changes to etc/uams/uams_krb4/kuam.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Rittau
  • Date: 2004-01-19 12:43:49 UTC
  • Revision ID: james.westby@ubuntu.com-20040119124349-es563jbp0hk0ae51
Tags: upstream-1.6.4
ImportĀ upstreamĀ versionĀ 1.6.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Id: kuam.c,v 1.4 2001/06/25 20:13:45 rufustfirefly Exp $
 
3
 *
 
4
 * Copyright (c) 1990,1994 Regents of The University of Michigan.
 
5
 * All Rights Reserved.  See COPYRIGHT.
 
6
 */
 
7
 
 
8
#ifdef HAVE_CONFIG_H
 
9
#include "config.h"
 
10
#endif /* HAVE_CONFIG_H */
 
11
 
 
12
#ifdef UAM_AFSKRB
 
13
 
 
14
#include <mit-copyright.h>
 
15
#include <krb.h>
 
16
#include <des.h>
 
17
#include <prot.h>
 
18
 
 
19
#include <stdio.h>
 
20
#include <string.h>
 
21
#include <errno.h>
 
22
 
 
23
/* use the bsd time.h struct defs for PC too! */
 
24
#include <sys/time.h>
 
25
#include <sys/types.h>
 
26
 
 
27
int     swap_bytes;
 
28
 
 
29
/*
 
30
 * krb_get_in_tkt() gets a ticket for a given principal to use a given
 
31
 * service and stores the returned ticket and session key for future
 
32
 * use.
 
33
 *
 
34
 * The "user", "instance", and "realm" arguments give the identity of
 
35
 * the client who will use the ticket.  The "service" and "sinstance"
 
36
 * arguments give the identity of the server that the client wishes
 
37
 * to use.  (The realm of the server is the same as the Kerberos server
 
38
 * to whom the request is sent.)  The "life" argument indicates the
 
39
 * desired lifetime of the ticket; the "key_proc" argument is a pointer
 
40
 * to the routine used for getting the client's private key to decrypt
 
41
 * the reply from Kerberos.  The "decrypt_proc" argument is a pointer
 
42
 * to the routine used to decrypt the reply from Kerberos; and "arg"
 
43
 * is an argument to be passed on to the "key_proc" routine.
 
44
 *
 
45
 * If all goes well, krb_get_in_tkt() returns INTK_OK, otherwise it
 
46
 * returns an error code:  If an AUTH_MSG_ERR_REPLY packet is returned
 
47
 * by Kerberos, then the error code it contains is returned.  Other
 
48
 * error codes returned by this routine include INTK_PROT to indicate
 
49
 * wrong protocol version, INTK_BADPW to indicate bad password (if
 
50
 * decrypted ticket didn't make sense), INTK_ERR if the ticket was for
 
51
 * the wrong server or the ticket store couldn't be initialized.
 
52
 *
 
53
 * The format of the message sent to Kerberos is as follows:
 
54
 *
 
55
 * Size                 Variable                Field
 
56
 * ----                 --------                -----
 
57
 *
 
58
 * 1 byte               KRB_PROT_VERSION        protocol version number
 
59
 * 1 byte               AUTH_MSG_KDC_REQUEST |  message type
 
60
 *                      HOST_BYTE_ORDER         local byte order in lsb
 
61
 * string               user                    client's name
 
62
 * string               instance                client's instance
 
63
 * string               realm                   client's realm
 
64
 * 4 bytes              tlocal.tv_sec           timestamp in seconds
 
65
 * 1 byte               life                    desired lifetime
 
66
 * string               service                 service's name
 
67
 * string               sinstance               service's instance
 
68
 */
 
69
 
 
70
kuam_get_in_tkt(user, instance, realm, service, sinstance, life, rpkt )
 
71
    char        *user;
 
72
    char        *instance;
 
73
    char        *realm;
 
74
    char        *service;
 
75
    char        *sinstance;
 
76
    int         life;
 
77
    KTEXT       rpkt;
 
78
{
 
79
    KTEXT_ST pkt_st;
 
80
    KTEXT pkt = &pkt_st;        /* Packet to KDC */
 
81
    KTEXT_ST cip_st;
 
82
    KTEXT cip = &cip_st;        /* Returned Ciphertext */
 
83
    KTEXT_ST tkt_st;
 
84
    KTEXT tkt = &tkt_st;        /* Current ticket */
 
85
    unsigned char *v = pkt->dat; /* Prot vers no */
 
86
    unsigned char *t = (pkt->dat+1); /* Prot msg type */
 
87
    int msg_byte_order;
 
88
    int kerror;
 
89
    struct timeval t_local;
 
90
    u_int32_t rep_err_code;
 
91
 
 
92
 
 
93
    /* BUILD REQUEST PACKET */
 
94
 
 
95
    /* Set up the fixed part of the packet */
 
96
    *v = (unsigned char) KRB_PROT_VERSION;
 
97
    *t = (unsigned char) AUTH_MSG_KDC_REQUEST;
 
98
    *t |= HOST_BYTE_ORDER;
 
99
 
 
100
    /* Now for the variable info */
 
101
    (void) strcpy((char *)(pkt->dat+2),user); /* aname */
 
102
    pkt->length = 3 + strlen(user);
 
103
    (void) strcpy((char *)(pkt->dat+pkt->length),
 
104
                  instance);    /* instance */
 
105
    pkt->length += 1 + strlen(instance);
 
106
    (void) strcpy((char *)(pkt->dat+pkt->length),realm); /* realm */
 
107
    pkt->length += 1 + strlen(realm);
 
108
 
 
109
    (void) gettimeofday(&t_local,(struct timezone *) 0);
 
110
    /* timestamp */
 
111
    memcpy((pkt->dat+pkt->length), &(t_local.tv_sec), 4);
 
112
    pkt->length += 4;
 
113
 
 
114
    *(pkt->dat+(pkt->length)++) = (char) life;
 
115
    (void) strcpy((char *)(pkt->dat+pkt->length),service);
 
116
    pkt->length += 1 + strlen(service);
 
117
    (void) strcpy((char *)(pkt->dat+pkt->length),sinstance);
 
118
    pkt->length += 1 + strlen(sinstance);
 
119
 
 
120
    rpkt->length = 0;
 
121
 
 
122
    /* SEND THE REQUEST AND RECEIVE THE RETURN PACKET */
 
123
 
 
124
    if (kerror = send_to_kdc(pkt, rpkt, realm)) return(kerror);
 
125
 
 
126
    /* check packet version of the returned packet */
 
127
    if (pkt_version(rpkt) != KRB_PROT_VERSION)
 
128
        return(INTK_PROT);
 
129
 
 
130
    /* Check byte order */
 
131
    msg_byte_order = pkt_msg_type(rpkt) & 1;
 
132
    swap_bytes = 0;
 
133
    if (msg_byte_order != HOST_BYTE_ORDER) {
 
134
        swap_bytes++;
 
135
    }
 
136
 
 
137
    switch (pkt_msg_type(rpkt) & ~1) {
 
138
    case AUTH_MSG_KDC_REPLY:
 
139
        break;
 
140
    case AUTH_MSG_ERR_REPLY:
 
141
        memcpy(&rep_err_code,pkt_err_code(rpkt),4);
 
142
        if (swap_bytes) swap_u_long(rep_err_code);
 
143
        return((int)rep_err_code);
 
144
    default:
 
145
        return(INTK_PROT);
 
146
    }
 
147
 
 
148
    return( INTK_OK );
 
149
}
 
150
 
 
151
kuam_set_in_tkt( user, instance, realm, service, sinstance, ptr)
 
152
    char        *user, *instance, *realm, *service, *sinstance, *ptr;
 
153
{
 
154
    KTEXT_ST            tkt_st;
 
155
    KTEXT               tkt = &tkt_st;
 
156
    struct timeval      t_local;
 
157
    int                 lifetime, kvno, kerror;
 
158
    int32_t             kdc_time;
 
159
    C_Block             ses;
 
160
    char                s_name[ SNAME_SZ ], s_instance[ INST_SZ ];
 
161
    char                rlm[ REALM_SZ ];
 
162
 
 
163
    /* extract session key */
 
164
    memcpy(ses, ptr, 8);
 
165
    ptr += 8;
 
166
 
 
167
    /* extract server's name */
 
168
    (void) strcpy(s_name,ptr);
 
169
    ptr += strlen(s_name) + 1;
 
170
 
 
171
    /* extract server's instance */
 
172
    (void) strcpy(s_instance,ptr);
 
173
    ptr += strlen(s_instance) + 1;
 
174
 
 
175
    /* extract server's realm */
 
176
    (void) strcpy(rlm,ptr);
 
177
    ptr += strlen(rlm) + 1;
 
178
 
 
179
    /* extract ticket lifetime, server key version, ticket length */
 
180
    /* be sure to avoid sign extension on lifetime! */
 
181
    lifetime = (unsigned char) ptr[0];
 
182
    kvno = (unsigned char) ptr[1];
 
183
    tkt->length = (unsigned char) ptr[2];
 
184
    ptr += 3;
 
185
 
 
186
    /* extract ticket itself */
 
187
    memcpy( tkt->dat, ptr, tkt->length);
 
188
    ptr += tkt->length;
 
189
 
 
190
    if (strcmp(s_name, service) || strcmp(s_instance, sinstance) ||
 
191
        strcmp(rlm, realm))     /* not what we asked for */
 
192
        return(INTK_ERR);       /* we need a better code here XXX */
 
193
 
 
194
    /* check KDC time stamp */
 
195
    memcpy(&kdc_time, ptr, 4); /* Time (coarse) */
 
196
    if (swap_bytes) swap_u_long(kdc_time);
 
197
 
 
198
    ptr += 4;
 
199
 
 
200
    (void) gettimeofday(&t_local,(struct timezone *) 0);
 
201
    if (abs((int)(t_local.tv_sec - kdc_time)) > CLOCK_SKEW) {
 
202
        return(RD_AP_TIME);             /* XXX should probably be better
 
203
                                           code */
 
204
    }
 
205
 
 
206
    /* initialize ticket cache */
 
207
    if (in_tkt(user,instance) != KSUCCESS)
 
208
        return(INTK_ERR);
 
209
 
 
210
    /* stash ticket, session key, etc. for future use */
 
211
    if (kerror = save_credentials(s_name, s_instance, rlm, ses,
 
212
                                  lifetime, kvno, tkt, t_local.tv_sec))
 
213
        return(kerror);
 
214
 
 
215
    return(INTK_OK);
 
216
}
 
217
 
 
218
#endif /* UAM_AFSKRB */