ReactOS 0.4.16-dev-306-g647d351
svc_auth_des.c File Reference
#include <wintirpc.h>
#include <reentrant.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <rpc/des_crypt.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
#include <rpc/auth_des.h>
#include <rpc/svc.h>
#include <rpc/rpc_msg.h>
#include <rpc/svc_auth.h>
#include <libc_private.h>
Include dependency graph for svc_auth_des.c:

Go to the source code of this file.

Classes

struct  cache_entry
 

Macros

#define debug(msg)   printf("svcauth_des: %s\n", msg)
 
#define USEC_PER_SEC   ((u_long) 1000000L)
 
#define BEFORE(t1, t2)   timercmp(t1, t2, <)
 
#define AUTHDES_CACHESZ   64
 

Functions

int key_decryptsession_pk (const char *, netobj *, des_block *)
 
static void cache_init ()
 
static short cache_spot ()
 
static void cache_ref ()
 
static void invalidate ()
 
enum auth_stat _svcauth_des (struct svc_req *rqst, struct rpc_msg *msg)
 
static short cache_victim ()
 
static void cache_ref (short sid)
 
static short cache_spot (des_block *key, char *name, struct timeval *timestamp)
 

Variables

static struct cache_entryauthdes_cache
 
static shortauthdes_lru
 
struct {
   u_long   ncachehits
 
   u_long   ncachereplays
 
   u_long   ncachemisses
 
svcauthdes_stats
 

Macro Definition Documentation

◆ AUTHDES_CACHESZ

#define AUTHDES_CACHESZ   64

Definition at line 76 of file svc_auth_des.c.

◆ BEFORE

#define BEFORE (   t1,
  t2 
)    timercmp(t1, t2, <)

Definition at line 71 of file svc_auth_des.c.

◆ debug

#define debug (   msg)    printf("svcauth_des: %s\n", msg)

Definition at line 68 of file svc_auth_des.c.

◆ USEC_PER_SEC

#define USEC_PER_SEC   ((u_long) 1000000L)

Definition at line 70 of file svc_auth_des.c.

Function Documentation

◆ _svcauth_des()

enum auth_stat _svcauth_des ( struct svc_req rqst,
struct rpc_msg msg 
)

Definition at line 106 of file svc_auth_des.c.

109{
110
111 long *ixdr;
112 des_block cryptbuf[2];
113 struct authdes_cred *cred;
114 struct authdes_verf verf;
115 int status;
116 struct cache_entry *entry;
117 short sid = 0;
118 des_block *sessionkey;
119 des_block ivec;
121 struct timeval timestamp;
123 struct area {
124 struct authdes_cred area_cred;
125 char area_netname[MAXNETNAMELEN+1];
126 } *area;
127
128 if (authdes_cache == NULL) {
129 cache_init();
130 }
131
132 area = (struct area *)rqst->rq_clntcred;
133 cred = (struct authdes_cred *)&area->area_cred;
134
135 /*
136 * Get the credential
137 */
138 ixdr = (long *)msg->rm_call.cb_cred.oa_base;
139 cred->adc_namekind = IXDR_GET_ENUM(ixdr, enum authdes_namekind);
140 switch (cred->adc_namekind) {
141 case ADN_FULLNAME:
142 namelen = IXDR_GET_U_LONG(ixdr);
143 if (namelen > MAXNETNAMELEN) {
144 return (AUTH_BADCRED);
145 }
146 cred->adc_fullname.name = area->area_netname;
147 bcopy((char *)ixdr, cred->adc_fullname.name,
148 (u_int)namelen);
149 cred->adc_fullname.name[namelen] = 0;
150 ixdr += (RNDUP(namelen) / BYTES_PER_XDR_UNIT);
151 cred->adc_fullname.key.key.high = (u_long)*ixdr++;
152 cred->adc_fullname.key.key.low = (u_long)*ixdr++;
153 cred->adc_fullname.window = (u_long)*ixdr++;
154 break;
155 case ADN_NICKNAME:
156 cred->adc_nickname = (u_long)*ixdr++;
157 break;
158 default:
159 return (AUTH_BADCRED);
160 }
161
162 /*
163 * Get the verifier
164 */
165 ixdr = (long *)msg->rm_call.cb_verf.oa_base;
166 verf.adv_xtimestamp.key.high = (u_long)*ixdr++;
167 verf.adv_xtimestamp.key.low = (u_long)*ixdr++;
168 verf.adv_int_u = (u_long)*ixdr++;
169
170
171 /*
172 * Get the conversation key
173 */
174 if (cred->adc_namekind == ADN_FULLNAME) {
175 netobj pkey;
176 char pkey_data[1024];
177
178 sessionkey = &cred->adc_fullname.key;
179 if (! getpublickey(cred->adc_fullname.name, pkey_data)) {
180 debug("getpublickey");
181 return(AUTH_BADCRED);
182 }
183 pkey.n_bytes = pkey_data;
184 pkey.n_len = strlen(pkey_data) + 1;
185 if (key_decryptsession_pk(cred->adc_fullname.name, &pkey,
186 sessionkey) < 0) {
187 debug("decryptsessionkey");
188 return (AUTH_BADCRED); /* key not found */
189 }
190 } else { /* ADN_NICKNAME */
191 sid = (short)cred->adc_nickname;
192 if (sid < 0 || sid >= AUTHDES_CACHESZ) {
193 debug("bad nickname");
194 return (AUTH_BADCRED); /* garbled credential */
195 }
196 sessionkey = &authdes_cache[sid].key;
197 }
198
199
200 /*
201 * Decrypt the timestamp
202 */
203 cryptbuf[0] = verf.adv_xtimestamp;
204 if (cred->adc_namekind == ADN_FULLNAME) {
205 cryptbuf[1].key.high = cred->adc_fullname.window;
206 cryptbuf[1].key.low = verf.adv_winverf;
207 ivec.key.high = ivec.key.low = 0;
208 status = cbc_crypt((char *)sessionkey, (char *)cryptbuf,
209 2*sizeof(des_block), DES_DECRYPT | DES_HW,
210 (char *)&ivec);
211 } else {
212 status = ecb_crypt((char *)sessionkey, (char *)cryptbuf,
213 sizeof(des_block), DES_DECRYPT | DES_HW);
214 }
215 if (DES_FAILED(status)) {
216 debug("decryption failure");
217 return (AUTH_FAILED); /* system error */
218 }
219
220 /*
221 * XDR the decrypted timestamp
222 */
223 ixdr = (long *)cryptbuf;
224 timestamp.tv_sec = IXDR_GET_LONG(ixdr);
225 timestamp.tv_usec = IXDR_GET_LONG(ixdr);
226
227 /*
228 * Check for valid credentials and verifiers.
229 * They could be invalid because the key was flushed
230 * out of the cache, and so a new session should begin.
231 * Be sure and send AUTH_REJECTED{CRED, VERF} if this is the case.
232 */
233 {
234 struct timeval current;
235 int nick;
236 int winverf;
237
238 if (cred->adc_namekind == ADN_FULLNAME) {
239 window = IXDR_GET_U_LONG(ixdr);
240 winverf = IXDR_GET_U_LONG(ixdr);
241 if (winverf != window - 1) {
242 debug("window verifier mismatch");
243 return (AUTH_BADCRED); /* garbled credential */
244 }
245 sid = cache_spot(sessionkey, cred->adc_fullname.name,
246 &timestamp);
247 if (sid < 0) {
248 debug("replayed credential");
249 return (AUTH_REJECTEDCRED); /* replay */
250 }
251 nick = 0;
252 } else { /* ADN_NICKNAME */
253 window = authdes_cache[sid].window;
254 nick = 1;
255 }
256
257 if ((u_long)timestamp.tv_usec >= USEC_PER_SEC) {
258 debug("invalid usecs");
259 /* cached out (bad key), or garbled verifier */
260 return (nick ? AUTH_REJECTEDVERF : AUTH_BADVERF);
261 }
262 if (nick && BEFORE(&timestamp,
263 &authdes_cache[sid].laststamp)) {
264 debug("timestamp before last seen");
265 return (AUTH_REJECTEDVERF); /* replay */
266 }
267 (void) gettimeofday(&current, (struct timezone *)NULL);
268 current.tv_sec -= window; /* allow for expiration */
269 if (!BEFORE(&current, &timestamp)) {
270 debug("timestamp expired");
271 /* replay, or garbled credential */
272 return (nick ? AUTH_REJECTEDVERF : AUTH_BADCRED);
273 }
274 }
275
276 /*
277 * Set up the reply verifier
278 */
279 verf.adv_nickname = (u_long)sid;
280
281 /*
282 * xdr the timestamp before encrypting
283 */
284 ixdr = (long *)cryptbuf;
285 IXDR_PUT_LONG(ixdr, timestamp.tv_sec - 1);
286 IXDR_PUT_LONG(ixdr, timestamp.tv_usec);
287
288 /*
289 * encrypt the timestamp
290 */
291 status = ecb_crypt((char *)sessionkey, (char *)cryptbuf,
292 sizeof(des_block), DES_ENCRYPT | DES_HW);
293 if (DES_FAILED(status)) {
294 debug("encryption failure");
295 return (AUTH_FAILED); /* system error */
296 }
297 verf.adv_xtimestamp = cryptbuf[0];
298
299 /*
300 * Serialize the reply verifier, and update rqst
301 */
302 ixdr = (long *)msg->rm_call.cb_verf.oa_base;
303 *ixdr++ = (long)verf.adv_xtimestamp.key.high;
304 *ixdr++ = (long)verf.adv_xtimestamp.key.low;
305 *ixdr++ = (long)verf.adv_int_u;
306
307 rqst->rq_xprt->xp_verf.oa_flavor = AUTH_DES;
308 rqst->rq_xprt->xp_verf.oa_base = msg->rm_call.cb_verf.oa_base;
309 rqst->rq_xprt->xp_verf.oa_length =
310 (char *)ixdr - msg->rm_call.cb_verf.oa_base;
311
312 /*
313 * We succeeded, commit the data to the cache now and
314 * finish cooking the credential.
315 */
317 entry->laststamp = timestamp;
318 cache_ref(sid);
319 if (cred->adc_namekind == ADN_FULLNAME) {
320 cred->adc_fullname.window = window;
321 cred->adc_nickname = (u_long)sid; /* save nickname */
322 if (entry->rname != NULL) {
323 mem_free(entry->rname, strlen(entry->rname) + 1);
324 }
325 entry->rname = (char *)mem_alloc((u_int)strlen(cred->adc_fullname.name)
326 + 1);
327 if (entry->rname != NULL) {
328 (void) strcpy(entry->rname, cred->adc_fullname.name);
329 } else {
330 debug("out of memory");
331 }
332 entry->key = *sessionkey;
333 entry->window = window;
334 invalidate(entry->localcred); /* mark any cached cred invalid */
335 } else { /* ADN_NICKNAME */
336 /*
337 * nicknames are cooked into fullnames
338 */
340 cred->adc_fullname.name = entry->rname;
341 cred->adc_fullname.key = entry->key;
342 cred->adc_fullname.window = entry->window;
343 }
344 return (AUTH_OK); /* we made it!*/
345}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define gettimeofday(tv, tz)
Definition: adns_win32.h:159
#define MAXNETNAMELEN
Definition: auth.h:78
@ AUTH_REJECTEDVERF
Definition: auth.h:152
@ AUTH_FAILED
Definition: auth.h:158
@ AUTH_BADCRED
Definition: auth.h:149
@ AUTH_BADVERF
Definition: auth.h:151
@ AUTH_OK
Definition: auth.h:145
@ AUTH_REJECTEDCRED
Definition: auth.h:150
#define AUTH_DES
Definition: auth.h:407
authdes_namekind
Definition: auth_des.h:50
@ ADN_FULLNAME
Definition: auth_des.h:51
@ ADN_NICKNAME
Definition: auth_des.h:52
#define msg(x)
Definition: auth_time.c:54
#define bcopy(s1, s2, n)
Definition: various.h:25
FT_UInt sid
Definition: cffcmap.c:139
int cbc_crypt(char *key, char *buf, unsigned len, unsigned mode, char *ivec)
Definition: des_crypt.c:75
int ecb_crypt(char *key, char *buf, unsigned len, unsigned mode)
Definition: des_crypt.c:102
#define DES_HW
Definition: des_crypt.h:56
#define DES_FAILED(err)
Definition: des_crypt.h:65
#define DES_DECRYPT
Definition: des_crypt.h:52
#define DES_ENCRYPT
Definition: des_crypt.h:51
UINT32 u_int
Definition: types.h:82
#define mem_free(ptr, bsize)
Definition: types.h:124
#define NULL
Definition: types.h:112
#define mem_alloc(bsize)
Definition: types.h:123
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
unsigned long u_long
Definition: linux.h:269
int getpublickey(char *netname, char *publickey) const
Definition: getpublickey.c:166
GLint namelen
Definition: glext.h:7232
uint32_t entry
Definition: isohybrid.c:63
if(dx< 0)
Definition: linetemp.h:194
struct task_struct * current
Definition: linux.c:32
static IHTMLWindow2 * window
Definition: events.c:77
static Real area(Real A[2], Real B[2], Real C[2])
Definition: polyDBG.cc:50
#define long
Definition: qsort.c:33
struct opaque_auth xp_verf
Definition: svc.h:121
u_int32_t adc_nickname
Definition: auth_des.h:74
struct authdes_fullname adc_fullname
Definition: auth_des.h:72
enum authdes_namekind adc_namekind
Definition: auth_des.h:71
Definition: svc_auth_des.c:77
Definition: xdr.h:332
u_int n_len
Definition: xdr.h:333
char * n_bytes
Definition: xdr.h:334
Definition: ps.c:97
void * rq_clntcred
Definition: svc.h:138
SVCXPRT * rq_xprt
Definition: svc.h:139
Definition: fake.h:14
#define debug(msg)
Definition: svc_auth_des.c:68
#define BEFORE(t1, t2)
Definition: svc_auth_des.c:71
static void cache_init()
Definition: svc_auth_des.c:352
#define USEC_PER_SEC
Definition: svc_auth_des.c:70
int key_decryptsession_pk(const char *, netobj *, des_block *)
#define AUTHDES_CACHESZ
Definition: svc_auth_des.c:76
static struct cache_entry * authdes_cache
Definition: svc_auth_des.c:84
static void invalidate()
static void cache_ref()
static short cache_spot()
struct des_block::@188 key
#define IXDR_GET_ENUM(buf, t)
Definition: xdr.h:276
#define IXDR_GET_U_LONG(buf)
Definition: xdr.h:277
#define BYTES_PER_XDR_UNIT
Definition: xdr.h:93
#define IXDR_GET_LONG(buf)
Definition: xdr.h:272
#define IXDR_PUT_LONG(buf, v)
Definition: xdr.h:273
#define RNDUP(x)
Definition: xdr.h:94

Referenced by _authenticate().

◆ cache_init()

static void cache_init ( )
static

Definition at line 352 of file svc_auth_des.c.

353{
354 int i;
355
356 authdes_cache = (struct cache_entry *)
357 mem_alloc(sizeof(struct cache_entry) * AUTHDES_CACHESZ);
358 bzero((char *)authdes_cache,
359 sizeof(struct cache_entry) * AUTHDES_CACHESZ);
360
361 authdes_lru = (short *)mem_alloc(sizeof(short) * AUTHDES_CACHESZ);
362 /*
363 * Initialize the lru list
364 */
365 for (i = 0; i < AUTHDES_CACHESZ; i++) {
366 authdes_lru[i] = i;
367 }
368}
#define bzero(s, n)
Definition: various.h:27
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static short * authdes_lru
Definition: svc_auth_des.c:85

Referenced by _svcauth_des(), and nfs41_idmap_create().

◆ cache_ref() [1/2]

static void cache_ref ( )
static

Referenced by _svcauth_des().

◆ cache_ref() [2/2]

static void cache_ref ( short  sid)
static

Definition at line 384 of file svc_auth_des.c.

386{
387 int i;
388 short curr;
389 short prev;
390
391 prev = authdes_lru[0];
392 authdes_lru[0] = sid;
393 for (i = 1; prev != sid; i++) {
394 curr = authdes_lru[i];
395 authdes_lru[i] = prev;
396 prev = curr;
397 }
398}

◆ cache_spot() [1/2]

static short cache_spot ( )
static

Referenced by _svcauth_des().

◆ cache_spot() [2/2]

static short cache_spot ( des_block key,
char name,
struct timeval timestamp 
)
static

Definition at line 407 of file svc_auth_des.c.

411{
412 struct cache_entry *cp;
413 int i;
414 u_long hi;
415
416 hi = key->key.high;
417 for (cp = authdes_cache, i = 0; i < AUTHDES_CACHESZ; i++, cp++) {
418 if (cp->key.key.high == hi &&
419 cp->key.key.low == key->key.low &&
420 cp->rname != NULL &&
421 bcmp(cp->rname, name, strlen(name) + 1) == 0) {
422 if (BEFORE(timestamp, &cp->laststamp)) {
423 svcauthdes_stats.ncachereplays++;
424 return (-1); /* replay */
425 }
426 svcauthdes_stats.ncachehits++;
427 return (i); /* refresh */
428 }
429 }
430 svcauthdes_stats.ncachemisses++;
431 return (cache_victim()); /* new credential */
432}
#define bcmp(s1, s2, n)
Definition: various.h:26
POINT cp
Definition: magnifier.c:59
Definition: copy.c:22
Definition: name.c:39
static struct @185 svcauthdes_stats
static short cache_victim()
Definition: svc_auth_des.c:375

◆ cache_victim()

static short cache_victim ( )
static

Definition at line 375 of file svc_auth_des.c.

376{
377 return (authdes_lru[AUTHDES_CACHESZ-1]);
378}

Referenced by cache_spot().

◆ invalidate()

static void invalidate ( )
static

Referenced by _svcauth_des().

◆ key_decryptsession_pk()

int key_decryptsession_pk ( const char ,
netobj ,
des_block  
)

Referenced by _svcauth_des().

Variable Documentation

◆ authdes_cache

struct cache_entry* authdes_cache
static

Definition at line 84 of file svc_auth_des.c.

Referenced by _svcauth_des(), cache_init(), and cache_spot().

◆ authdes_lru

short* authdes_lru
static

Definition at line 85 of file svc_auth_des.c.

Referenced by cache_init(), cache_ref(), and cache_victim().

◆ ncachehits

u_long ncachehits

Definition at line 97 of file svc_auth_des.c.

◆ ncachemisses

u_long ncachemisses

Definition at line 99 of file svc_auth_des.c.

◆ ncachereplays

u_long ncachereplays

Definition at line 98 of file svc_auth_des.c.

◆ 

struct { ... } svcauthdes_stats

Referenced by cache_spot().