1 /***************************************************************************
2 begin : Thu Aug 01 2019
3 copyright : (C) 2019 by Martin Preuss
4 email : martin@libchipcard.de
5
6 ***************************************************************************
7 * This file is part of the project "AqBanking". *
8 * Please see toplevel file COPYING of that project for license details. *
9 ***************************************************************************/
10
11 #ifdef HAVE_CONFIG_H
12 # include <config.h>
13 #endif
14
15
16 #include "./session.h"
17 #include "s_message.h"
18
19 #include "service/bpd/bpd_read.h"
20
21 #include <gwenhywfar/debug.h>
22
23
24
25 /* ------------------------------------------------------------------------------------------------
26 * forward declarations
27 * ------------------------------------------------------------------------------------------------
28 */
29
30 static AQFINTS_MESSAGE *createMessage(AQFINTS_SESSION *sess, const char *bankCode);
31 static int mkGetAnonBpdMessage(AQFINTS_SESSION *sess, const char *bankCode, GWEN_BUFFER *destBuffer);
32 static AQFINTS_BPD *extractBpd(AQFINTS_SESSION *sess, const uint8_t *ptrBuffer, uint32_t lenBuffer);
33
34
35
36 /* ------------------------------------------------------------------------------------------------
37 * implementations
38 * ------------------------------------------------------------------------------------------------
39 */
40
41
42
AQFINTS_Session_GetAnonBpd(AQFINTS_SESSION * sess,const char * bankCode,AQFINTS_BPD ** pBpd)43 int AQFINTS_Session_GetAnonBpd(AQFINTS_SESSION *sess, const char *bankCode, AQFINTS_BPD **pBpd)
44 {
45 GWEN_BUFFER *destBuffer;
46 int rv;
47 AQFINTS_BPD *bpd;
48
49 destBuffer=GWEN_Buffer_new(0, 256, 0, 1);
50 rv=mkGetAnonBpdMessage(sess, bankCode, destBuffer);
51 if (rv<0) {
52 DBG_ERROR(AQFINTS_LOGDOMAIN, "here (%d)", rv);
53 GWEN_Buffer_free(destBuffer);
54 return rv;
55 }
56
57 rv=AQFINTS_Session_Connect(sess);
58 if (rv<0) {
59 DBG_ERROR(AQFINTS_LOGDOMAIN, "here (%d)", rv);
60 GWEN_Buffer_free(destBuffer);
61 return rv;
62 }
63
64 rv=AQFINTS_Session_SendMessage(sess,
65 GWEN_Buffer_GetStart(destBuffer),
66 GWEN_Buffer_GetUsedBytes(destBuffer));
67 if (rv<0) {
68 DBG_ERROR(AQFINTS_LOGDOMAIN, "here (%d)", rv);
69 AQFINTS_Session_Disconnect(sess);
70 GWEN_Buffer_free(destBuffer);
71 return rv;
72 }
73
74 GWEN_Buffer_Reset(destBuffer);
75
76 rv=AQFINTS_Session_ReceiveMessage(sess, destBuffer);
77 if (rv<0) {
78 DBG_ERROR(AQFINTS_LOGDOMAIN, "here (%d)", rv);
79 AQFINTS_Session_Disconnect(sess);
80 GWEN_Buffer_free(destBuffer);
81 return rv;
82 }
83
84 AQFINTS_Session_Disconnect(sess);
85
86 bpd=extractBpd(sess,
87 (const uint8_t *) GWEN_Buffer_GetStart(destBuffer),
88 GWEN_Buffer_GetUsedBytes(destBuffer));
89 if (bpd==NULL) {
90 DBG_ERROR(AQFINTS_LOGDOMAIN, "No BPD extracted");
91 GWEN_Buffer_free(destBuffer);
92 return rv;
93 }
94
95 GWEN_Buffer_free(destBuffer);
96
97 *pBpd=bpd;
98 return 0;
99 }
100
101
102
extractBpd(AQFINTS_SESSION * sess,const uint8_t * ptrBuffer,uint32_t lenBuffer)103 AQFINTS_BPD *extractBpd(AQFINTS_SESSION *sess, const uint8_t *ptrBuffer, uint32_t lenBuffer)
104 {
105 AQFINTS_SEGMENT_LIST *segmentList;
106 AQFINTS_PARSER *parser;
107 AQFINTS_BPD *bpd;
108 int rv;
109
110 parser=AQFINTS_Session_GetParser(sess);
111 segmentList=AQFINTS_Segment_List_new();
112 rv=AQFINTS_Parser_ReadIntoSegmentList(parser, segmentList, ptrBuffer, lenBuffer);
113 if (rv<0) {
114 DBG_ERROR(AQFINTS_LOGDOMAIN, "here (%d)", rv);
115 AQFINTS_Segment_List_free(segmentList);
116 return NULL;
117 }
118
119 rv=AQFINTS_Parser_ReadSegmentListToDb(parser, segmentList);
120 if (rv<0) {
121 DBG_ERROR(AQFINTS_LOGDOMAIN, "here (%d)", rv);
122 AQFINTS_Segment_List_free(segmentList);
123 return NULL;
124 }
125
126 bpd=AQFINTS_Session_ExtractBpdFromSegmentList(sess, segmentList);
127 if (bpd==NULL) {
128 DBG_ERROR(AQFINTS_LOGDOMAIN, "Empty BPD");
129 AQFINTS_Segment_List_free(segmentList);
130 return NULL;
131 }
132
133 AQFINTS_Segment_List_free(segmentList);
134 return bpd;
135 }
136
137
138
139
140
mkGetAnonBpdMessage(AQFINTS_SESSION * sess,const char * bankCode,GWEN_BUFFER * destBuffer)141 int mkGetAnonBpdMessage(AQFINTS_SESSION *sess, const char *bankCode, GWEN_BUFFER *destBuffer)
142 {
143 AQFINTS_MESSAGE *message;
144 AQFINTS_SEGMENT_LIST *segmentList;
145 AQFINTS_SEGMENT *segment;
146 int rv;
147
148 message=createMessage(sess, bankCode);
149 if (message==NULL) {
150 DBG_ERROR(AQFINTS_LOGDOMAIN, "No message created");
151 return GWEN_ERROR_INVALID;
152 }
153
154 segmentList=AQFINTS_Message_GetSegmentList(message);
155
156 segment=AQFINTS_Segment_List_Last(segmentList);
157 assert(segment);
158
159 rv=AQFINTS_Session_WrapMessageHeadAndTail(sess, segmentList,
160 AQFINTS_Message_GetDialogId(message),
161 AQFINTS_Message_GetMessageNumber(message),
162 AQFINTS_Message_GetRefMessageNumber(message),
163 AQFINTS_Segment_GetSegmentNumber(segment));
164 if (rv<0) {
165 DBG_ERROR(AQFINTS_LOGDOMAIN, "here (%d)", rv);
166 AQFINTS_Message_free(message);
167 return rv;
168 }
169
170 AQFINTS_Segment_List_SampleBuffers(segmentList, destBuffer);
171 AQFINTS_Message_free(message);
172 return 0;
173 }
174
175
176
177
178
179
createMessage(AQFINTS_SESSION * sess,const char * bankCode)180 AQFINTS_MESSAGE *createMessage(AQFINTS_SESSION *sess, const char *bankCode)
181 {
182 AQFINTS_PARSER *parser;
183 int hbciVersion;
184 AQFINTS_MESSAGE *message;
185 AQFINTS_SEGMENT *defSegment;
186 AQFINTS_SEGMENT *segment;
187 GWEN_DB_NODE *dbSegment;
188
189 parser=AQFINTS_Session_GetParser(sess);
190 hbciVersion=AQFINTS_Session_GetHbciVersion(sess);
191
192 message=AQFINTS_Message_new();
193 AQFINTS_Message_SetMessageNumber(message, AQFINTS_Session_GetLastMessageNumSent(sess)+1);
194
195 /* ident */
196 defSegment=AQFINTS_Parser_FindSegmentHighestVersionForProto(parser, "HKIDN", hbciVersion);
197 if (defSegment==NULL) {
198 DBG_ERROR(AQFINTS_LOGDOMAIN, "No matching definition segment found for HKIDN (proto=%d)", hbciVersion);
199 return NULL;
200 }
201 segment=AQFINTS_Segment_new();
202 AQFINTS_Segment_copy(segment, defSegment);
203 dbSegment=GWEN_DB_Group_new("ident");
204 AQFINTS_Segment_SetDbData(segment, dbSegment);
205 GWEN_DB_SetIntValue(dbSegment, GWEN_DB_FLAGS_OVERWRITE_VARS, "country", 280);
206 GWEN_DB_SetCharValue(dbSegment, GWEN_DB_FLAGS_OVERWRITE_VARS, "bankCode", bankCode);
207 GWEN_DB_SetCharValue(dbSegment, GWEN_DB_FLAGS_OVERWRITE_VARS, "customerId", "9999999999");
208 GWEN_DB_SetCharValue(dbSegment, GWEN_DB_FLAGS_OVERWRITE_VARS, "systemId", "0");
209 GWEN_DB_SetIntValue(dbSegment, GWEN_DB_FLAGS_OVERWRITE_VARS, "status", 0);
210 AQFINTS_Message_AddSegment(message, segment);
211
212 /* prepare */
213 defSegment=AQFINTS_Parser_FindSegmentHighestVersionForProto(parser, "HKVVB", hbciVersion);
214 if (defSegment==NULL) {
215 DBG_ERROR(AQFINTS_LOGDOMAIN, "No matching definition segment found for HKVVB (proto=%d)", hbciVersion);
216 return NULL;
217 }
218 segment=AQFINTS_Segment_new();
219 AQFINTS_Segment_copy(segment, defSegment);
220 dbSegment=GWEN_DB_Group_new("ident");
221 AQFINTS_Segment_SetDbData(segment, dbSegment);
222 GWEN_DB_SetIntValue(dbSegment, GWEN_DB_FLAGS_OVERWRITE_VARS, "bpdVersion", 0);
223 GWEN_DB_SetIntValue(dbSegment, GWEN_DB_FLAGS_OVERWRITE_VARS, "updVersion", 0);
224 GWEN_DB_SetIntValue(dbSegment, GWEN_DB_FLAGS_OVERWRITE_VARS, "lang", 1);
225 GWEN_DB_SetCharValue(dbSegment, GWEN_DB_FLAGS_OVERWRITE_VARS, "product", "AqBanking");
226 GWEN_DB_SetCharValue(dbSegment, GWEN_DB_FLAGS_OVERWRITE_VARS, "version", "5.99");
227 AQFINTS_Message_AddSegment(message, segment);
228
229 return message;
230 }
231
232
233
234
235