Added authentication stuff.
[yaz-moved-to-github.git] / asn / proto.c
1 /*
2  * Copyright (C) 1994, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: proto.c,v $
7  * Revision 1.7  1995-03-07 16:29:33  quinn
8  * Added authentication stuff.
9  *
10  * Revision 1.6  1995/03/01  14:46:03  quinn
11  * Fixed protocol bug in 8777query.
12  *
13  * Revision 1.5  1995/02/14  11:54:22  quinn
14  * Fixing include.
15  *
16  * Revision 1.4  1995/02/10  15:54:30  quinn
17  * Small adjustments.
18  *
19  * Revision 1.3  1995/02/09  15:51:39  quinn
20  * Works better now.
21  *
22  * Revision 1.2  1995/02/06  21:26:07  quinn
23  * Repaired this evening's damages..
24  *
25  * Revision 1.1  1995/02/06  16:44:47  quinn
26  * First hack at Z/SR protocol
27  *
28  */
29
30 #include <odr.h>
31
32 #include <proto.h>
33
34 /* ---------------------- GLOBAL DEFS ------------------- */
35
36 int z_ReferenceId(ODR o, Z_ReferenceId **p, int opt)
37 {
38     return odr_implicit(o, odr_octetstring, (Odr_oct**) p, ODR_CONTEXT, 2, opt);
39 }
40
41 int z_DatabaseName(ODR o, Z_DatabaseName **p, int opt)
42 {
43     return odr_implicit(o, odr_visiblestring, (char **) p, ODR_CONTEXT, 105,
44         opt);
45 }
46
47 int z_ResultSetId(ODR o, char **p, int opt)
48 {
49     return odr_implicit(o, odr_visiblestring, (char **) p, ODR_CONTEXT, 31,
50         opt);
51 }
52
53 int z_UserInformationField(ODR o, Z_UserInformationField **p, int opt)
54 {
55     return odr_explicit(o, odr_external, (Odr_external **)p, ODR_CONTEXT,
56         11, opt);
57 }
58
59 /* ---------------------- INITIALIZE SERVICE ------------------- */
60
61 int z_InitRequest(ODR o, Z_InitRequest **p, int opt)
62 {
63     Z_InitRequest *pp;
64
65     if (!odr_sequence_begin(o, p, sizeof(**p)))
66         return opt;
67     pp = *p;
68     return
69         z_ReferenceId(o, &pp->referenceId, 1) &&
70         odr_implicit(o, odr_bitstring, &pp->protocolVersion, ODR_CONTEXT, 
71             3, 0) &&
72         odr_implicit(o, odr_bitstring, &pp->options, ODR_CONTEXT, 4, 0) &&
73         odr_implicit(o, odr_integer, &pp->preferredMessageSize, ODR_CONTEXT,
74             5, 0) &&
75         odr_implicit(o, odr_integer, &pp->maximumRecordSize, ODR_CONTEXT,
76             6, 0) &&
77         odr_explicit(o, odr_any, &pp->idAuthentication, ODR_CONTEXT,
78             7, 1) &&
79         odr_implicit(o, odr_visiblestring, &pp->implementationId, ODR_CONTEXT,
80             110, 1) &&
81         odr_implicit(o, odr_visiblestring, &pp->implementationName, ODR_CONTEXT,
82             111, 1) &&
83         odr_implicit(o, odr_visiblestring, &pp->implementationVersion,
84             ODR_CONTEXT, 112, 1) &&
85         z_UserInformationField(o, &pp->userInformationField, 1) &&
86         odr_sequence_end(o);
87 }
88
89 int z_InitResponse(ODR o, Z_InitResponse **p, int opt)
90 {
91     Z_InitResponse *pp;
92
93     if (!odr_sequence_begin(o, p, sizeof(**p)))
94         return opt;
95     pp = *p;
96     return
97         z_ReferenceId(o, &pp->referenceId, 1) &&
98         odr_implicit(o, odr_bitstring, &pp->protocolVersion, ODR_CONTEXT, 
99             3, 0) &&
100         odr_implicit(o, odr_bitstring, &pp->options, ODR_CONTEXT, 4, 0) &&
101         odr_implicit(o, odr_integer, &pp->preferredMessageSize, ODR_CONTEXT,
102             5, 0) &&
103         odr_implicit(o, odr_integer, &pp->maximumRecordSize, ODR_CONTEXT,
104             6, 0) &&
105         odr_implicit(o, odr_bool, &pp->result, ODR_CONTEXT, 12, 0) &&
106         odr_implicit(o, odr_visiblestring, &pp->implementationId, ODR_CONTEXT,
107             110, 1) &&
108         odr_implicit(o, odr_visiblestring, &pp->implementationName, ODR_CONTEXT,
109             111, 1) &&
110         odr_implicit(o, odr_visiblestring, &pp->implementationVersion,
111             ODR_CONTEXT, 112, 1) &&
112         z_UserInformationField(o, &pp->userInformationField, 1) &&
113         odr_sequence_end(o);
114 }
115
116 int z_NSRAuthentication(ODR o, Z_NSRAuthentication **p, int opt)
117 {
118     if (!odr_sequence_begin(o, p, sizeof(**p)))
119         return opt;
120     return
121         odr_visiblestring(o, &(*p)->user, 0) &&
122         odr_visiblestring(o, &(*p)->password, 0) &&
123         odr_visiblestring(o, &(*p)->account, 0) &&
124         odr_sequence_end(o);
125 }
126
127 int z_StrAuthentication(ODR o, char **p, int opt)
128 {
129     return odr_visiblestring(o, p, opt);
130 }
131
132 /* ------------------------ SEARCH SERVICE ----------------------- */
133
134 int z_ElementSetName(ODR o, char **p, int opt)
135 {
136     return odr_implicit(o, odr_visiblestring, (char**) p, ODR_CONTEXT, 103,
137         opt);
138 }
139
140 int z_PreferredRecordSyntax(ODR o, Z_PreferredRecordSyntax **p, int opt)
141 {
142     return odr_implicit(o, odr_oid, (Odr_oid**) p, ODR_CONTEXT, 104, opt);
143 }
144
145 int z_DatabaseSpecificUnit(ODR o, Z_DatabaseSpecificUnit **p, int opt)
146 {
147     if (!odr_sequence_begin(o, p, sizeof(**p)))
148         return opt;
149     return
150         z_DatabaseName(o, &(*p)->databaseName, 0) &&
151         z_ElementSetName(o, &(*p)->elementSetName, 0) &&
152         odr_sequence_end(o);
153 }
154
155 int z_DatabaseSpecific(ODR o, Z_DatabaseSpecific **p, int opt)
156 {
157     if (o->direction == ODR_DECODE)
158         *p = nalloc(o, sizeof(**p));
159     else if (!*p)
160         return opt;
161
162     odr_implicit_settag(o, ODR_CONTEXT, 1);
163     if (odr_sequence_of(o, z_DatabaseSpecificUnit, &(*p)->elements,
164         &(*p)->num_elements))
165         return 1;
166     *p = 0;
167     return 0;
168 }
169
170 int z_ElementSetNames(ODR o, Z_ElementSetNames **p, int opt)
171 {
172     static Odr_arm arm[] =
173     {
174         {ODR_IMPLICIT, ODR_CONTEXT, 0, Z_ElementSetNames_generic,
175             z_ElementSetName},
176         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_ElementSetNames_databaseSpecific,
177             z_DatabaseSpecific},
178         {-1, -1, -1, -1, 0}
179     };
180
181     if (!odr_constructed_begin(o, p, ODR_CONTEXT, 19))
182         return opt;
183
184     if (o->direction == ODR_DECODE)
185         *p = nalloc(o, sizeof(**p));
186
187     if (odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
188         odr_constructed_end(o))
189         return 1;
190     *p = 0;
191     return 0;
192 }
193
194 /* ----------------------- RPN QUERY -----------------------*/
195
196 int z_AttributeElement(ODR o, Z_AttributeElement **p, int opt)
197 {
198     if (!odr_sequence_begin(o, p, sizeof(**p)))
199         return opt;
200     return
201         odr_implicit(o, odr_integer, &(*p)->attributeType, ODR_CONTEXT,
202             120, 1) &&
203         odr_implicit(o, odr_integer, &(*p)->attributeValue, ODR_CONTEXT,
204             121, 1) &&
205         odr_sequence_end(o);
206 }
207
208 int z_AttributesPlusTerm(ODR o, Z_AttributesPlusTerm **p, int opt)
209 {
210     if (!(odr_implicit_settag(o, ODR_CONTEXT, 102) &&
211         odr_sequence_begin(o, p, sizeof(**p))))
212         return opt;
213     return
214         odr_implicit_settag(o, ODR_CONTEXT, 44) &&
215         odr_sequence_of(o, z_AttributeElement, &(*p)->attributeList,
216             &(*p)->num_attributes) &&
217         odr_implicit(o, odr_octetstring, &(*p)->term, ODR_CONTEXT, 45, 0) &&
218         odr_sequence_end(o);
219 }
220
221 int z_Operator(ODR o, Z_Operator **p, int opt)
222 {
223     static Odr_arm arm[] =
224     {
225         {ODR_IMPLICIT, ODR_CONTEXT, 0, Z_Operator_and, odr_null},
226         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_Operator_or, odr_null},
227         {ODR_IMPLICIT, ODR_CONTEXT, 2, Z_Operator_and_not, odr_null},
228         {-1, -1, -1, -1, 0}
229     };
230     int dummy = 999;
231
232     if (!*p && o->direction != ODR_DECODE)
233         return opt;
234     if (!odr_constructed_begin(o, p, ODR_CONTEXT, 46))
235         return opt;
236     if (o->direction == ODR_DECODE)
237         *p = nalloc(o, sizeof(**p));
238     else
239         (*p)->u.and = &dummy;
240
241     if (odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
242         odr_constructed_end(o))
243         return 1;
244     *p = 0;
245     return opt;
246 }
247
248 int z_Operand(ODR o, Z_Operand **p, int opt)
249 {
250     static Odr_arm arm[] =
251     {
252         {-1, -1, -1, Z_Operand_APT, z_AttributesPlusTerm},
253         {-1, -1, -1, Z_Operand_resultSetId, z_ResultSetId},
254         {-1, -1, -1, -1, 0}
255     };
256
257     if (o->direction ==ODR_DECODE)
258         *p = nalloc(o, sizeof(**p));
259     else if (!*p)
260         return opt;
261     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
262         return 1;
263     *p = 0;
264     return opt;
265 }
266
267 int z_RPNStructure(ODR o, Z_RPNStructure **p, int opt);
268
269 int z_Complex(ODR o, Z_Complex **p, int opt)
270 {
271     if (!odr_sequence_begin(o, p, sizeof(**p)))
272         return opt;
273     return
274         z_RPNStructure(o, &(*p)->s1, 0) &&
275         z_RPNStructure(o, &(*p)->s2, 0) &&
276         z_Operator(o, &(*p)->operator, 0) &&
277         odr_sequence_end(o);
278 }
279
280 int z_RPNStructure(ODR o, Z_RPNStructure **p, int opt)
281 {
282     static Odr_arm arm[] = 
283     {
284         {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_RPNStructure_simple, z_Operand},
285         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_RPNStructure_complex, z_Complex},
286         {-1 -1, -1, -1, 0}
287     };
288
289     if (o->direction == ODR_DECODE)
290         *p = nalloc(o, sizeof(**p));
291     else if (!*p)
292         return opt;
293     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
294         return 1;
295     *p = 0;
296     return opt;
297 }
298
299 int z_RPNQuery(ODR o, Z_RPNQuery **p, int opt)
300 {
301     if (!odr_sequence_begin(o, p, sizeof(**p)))
302         return opt;
303     return
304         odr_oid(o, &(*p)->attributeSetId, 0) &&
305         z_RPNStructure(o, &(*p)->RPNStructure, 0) &&
306         odr_sequence_end(o);
307 }
308
309 /* -----------------------END RPN QUERY ----------------------- */
310
311 int z_Query(ODR o, Z_Query **p, int opt)
312 {
313     static Odr_arm arm[] = 
314     {
315         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_Query_type_1, z_RPNQuery},
316         {ODR_EXPLICIT, ODR_CONTEXT, 2, Z_Query_type_2, odr_octetstring},
317         {-1, -1, -1, -1, 0}
318     };
319
320     if (o->direction == ODR_DECODE)
321         *p = nalloc(o, sizeof(**p));
322     else if (!*p)
323         return opt;
324     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
325         return 1;
326     *p = 0;
327     return opt;
328 }
329
330 int z_SearchRequest(ODR o, Z_SearchRequest **p, int opt)
331 {
332     Z_SearchRequest *pp;
333
334     if (!odr_sequence_begin(o, p, sizeof(**p)))
335         return opt;
336     pp = *p;
337     return
338         z_ReferenceId(o, &pp->referenceId, 1) &&
339         odr_implicit(o, odr_integer, &pp->smallSetUpperBound, ODR_CONTEXT,
340             13, 0) &&
341         odr_implicit(o, odr_integer, &pp->largeSetLowerBound, ODR_CONTEXT,
342             14, 0) &&
343         odr_implicit(o, odr_integer, &pp->mediumSetPresentNumber, ODR_CONTEXT,
344             15, 0) &&
345         odr_implicit(o, odr_bool, &pp->replaceIndicator, ODR_CONTEXT, 16, 1) &&
346         odr_implicit(o, odr_visiblestring, &pp->resultSetName, ODR_CONTEXT,
347             17, 9) &&
348         odr_implicit_settag(o, ODR_CONTEXT, 18) &&
349         odr_sequence_of(o, z_DatabaseName, &pp->databaseNames,
350             &pp->num_databaseNames) &&
351         odr_implicit(o, z_ElementSetNames, &pp->smallSetElementSetNames,
352             ODR_CONTEXT, 100, 1) &&
353         odr_implicit(o, z_ElementSetNames, &pp->mediumSetElementSetNames,
354             ODR_CONTEXT, 101, 1) &&
355         z_PreferredRecordSyntax(o, &pp->preferredRecordSyntax, 1) &&
356         odr_explicit(o, z_Query, &pp->query, ODR_CONTEXT, 21, 0) &&
357         odr_sequence_end(o);
358 }
359
360 /* ------------------------ RECORD ------------------------- */
361
362 int z_DatabaseRecord(ODR o, Z_DatabaseRecord **p, int opt)
363 {
364     return odr_external(o, (Odr_external **) p, opt);
365 }
366
367 int z_DiagRec(ODR o, Z_DiagRec **p, int opt)
368 {
369     if (!odr_sequence_begin(o, p, sizeof(**p)))
370         return opt;
371     return
372         odr_oid(o, &(*p)->diagnosticSetId, 1) &&       /* SHOULD NOT BE OPT */
373         odr_integer(o, &(*p)->condition, 0) &&
374         (odr_visiblestring(o, &(*p)->addinfo, 0) ||
375         odr_implicit(o, odr_cstring, &(*p)->addinfo, ODR_CONTEXT, ODR_VISIBLESTRING, 1)) &&
376         odr_sequence_end(o);
377 }
378
379 int z_NamePlusRecord(ODR o, Z_NamePlusRecord **p, int opt)
380 {
381     static Odr_arm arm[] =
382     {
383         {ODR_EXPLICIT, ODR_CONTEXT, 1, Z_NamePlusRecord_databaseRecord,
384             z_DatabaseRecord},
385         {ODR_EXPLICIT, ODR_CONTEXT, 2, Z_NamePlusRecord_surrogateDiagnostic,
386             z_DiagRec},
387         {-1, -1, -1, -1, 0}
388     };
389
390     if (!odr_sequence_begin(o, p, sizeof(**p)))
391         return opt;
392     return
393         odr_implicit(o, z_DatabaseName, &(*p)->databaseName, ODR_CONTEXT,
394             0, 1) &&
395         odr_constructed_begin(o, &(*p)->u, ODR_CONTEXT, 1) &&
396         odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
397         odr_constructed_end(o) &&
398         odr_sequence_end(o);
399 }
400
401 int z_NamePlusRecordList(ODR o, Z_NamePlusRecordList **p, int opt)
402 {
403     if (o->direction == ODR_DECODE)
404         *p = nalloc(o, sizeof(**p));
405     if (odr_sequence_of(o, z_NamePlusRecord, &(*p)->records,
406         &(*p)->num_records))
407         return 1;
408     *p = 0;
409     return 0;
410 }
411
412 int z_Records(ODR o, Z_Records **p, int opt)
413 {
414     Odr_arm arm[] = 
415     {
416         {ODR_IMPLICIT, ODR_CONTEXT, 28, Z_Records_DBOSD, z_NamePlusRecordList},
417         {ODR_IMPLICIT, ODR_CONTEXT, 130, Z_Records_NSD, z_DiagRec},
418         {-1, -1, -1, -1, 0}
419     };
420
421     if (o->direction == ODR_DECODE)
422         *p = nalloc(o, sizeof(**p));
423     else if (!*p)
424         return opt;
425     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
426         return 1;
427     *p = 0;
428     return opt;
429 }
430
431 /* ------------------------ SEARCHRESPONSE ----------------*/
432
433 int z_NumberOfRecordsReturned(ODR o, int **p, int opt)
434 {
435     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 24, opt);
436 }
437
438 int z_NextResultSetPosition(ODR o, int **p, int opt)
439 {
440     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 25, opt);
441 }
442
443 int z_PresentStatus(ODR o, int **p, int opt)
444 {
445     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 27, opt);
446 }
447
448 int z_SearchResponse(ODR o, Z_SearchResponse **p, int opt)
449 {
450     Z_SearchResponse *pp;
451
452     if (!odr_sequence_begin(o, p, sizeof(**p)))
453         return opt;
454     pp = *p;
455     return
456         z_ReferenceId(o, &pp->referenceId, 1) &&
457         odr_implicit(o, odr_integer, &pp->resultCount, ODR_CONTEXT, 23, 0) &&
458         z_NumberOfRecordsReturned(o, &pp->numberOfRecordsReturned, 0) &&
459         z_NextResultSetPosition(o, &pp->nextResultSetPosition, 0) &&
460         odr_implicit(o, odr_bool, &pp->searchStatus, ODR_CONTEXT, 22, 0) &&
461         odr_implicit(o, odr_integer, &pp->resultSetStatus, ODR_CONTEXT, 26, 1) &&
462         z_PresentStatus(o, &pp->presentStatus, 1) &&
463         z_Records(o, &pp->records, 1) &&
464         odr_sequence_end(o);
465 }
466
467 /* --------------------- PRESENT SERVICE ---------------------- */
468
469 int z_PresentRequest(ODR o, Z_PresentRequest **p, int opt)
470 {
471     Z_PresentRequest *pp;
472
473     if (!odr_sequence_begin(o, p, sizeof(**p)))
474         return opt;
475     pp = *p;
476     return
477         z_ReferenceId(o, &pp->referenceId, 1) &&
478         z_ResultSetId(o, &pp->resultSetId, 0) &&
479         odr_implicit(o, odr_integer, &pp->resultSetStartPoint, ODR_CONTEXT,
480             30, 0) &&
481         odr_implicit(o, odr_integer, &pp->numberOfRecordsRequested, ODR_CONTEXT,
482             29, 0) &&
483         z_ElementSetNames(o, &pp->elementSetNames, 1) &&
484         z_PreferredRecordSyntax(o, &pp->preferredRecordSyntax, 1) &&
485         odr_sequence_end(o);
486 }
487
488 int z_PresentResponse(ODR o, Z_PresentResponse **p, int opt)
489 {
490     Z_PresentResponse *pp;
491
492     if (!odr_sequence_begin(o, p, sizeof(**p)))
493         return opt;
494     pp = *p;
495     return
496         z_ReferenceId(o, &pp->referenceId, 1) &&
497         z_NumberOfRecordsReturned(o, &pp->numberOfRecordsReturned, 0) &&
498         z_NextResultSetPosition(o, &pp->nextResultSetPosition, 0) &&
499         z_PresentStatus(o, &pp->presentStatus, 0) &&
500         z_Records(o, &pp->records, 1) &&
501         odr_sequence_end(o);
502 }
503
504 /* ------------------------ APDU ------------------------- */
505
506 int z_APDU(ODR o, Z_APDU **p, int opt)
507 {
508     static Odr_arm arm[] =
509     {
510         {ODR_IMPLICIT, ODR_CONTEXT, 20, Z_APDU_initRequest, z_InitRequest},
511         {ODR_IMPLICIT, ODR_CONTEXT, 21, Z_APDU_initResponse, z_InitResponse},
512         {ODR_IMPLICIT, ODR_CONTEXT, 22, Z_APDU_searchRequest, z_SearchRequest},
513         {ODR_IMPLICIT, ODR_CONTEXT, 23, Z_APDU_searchResponse, z_SearchResponse},
514         {ODR_IMPLICIT, ODR_CONTEXT, 24, Z_APDU_presentRequest, z_PresentRequest},
515         {ODR_IMPLICIT, ODR_CONTEXT, 25, Z_APDU_presentResponse, z_PresentResponse},
516
517         {-1, -1, -1, -1, 0}
518     };
519
520     if (o->direction == ODR_DECODE)
521         *p = nalloc(o, sizeof(**p));
522     if (!odr_choice(o, arm, &(*p)->u, &(*p)->which))
523     {
524         if (o->direction == ODR_DECODE)
525         {
526             *p = 0;
527             return opt;
528         }
529     }
530     return 1;
531 }