]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/other/smux/utils.cpp
Merge branch 'stg-2.409-radius'
[stg.git] / projects / stargazer / plugins / other / smux / utils.cpp
1 #include <unistd.h> // write
2
3 #include <cstring> // memset
4 #include <cerrno>
5
6 #include "stg/common.h"
7
8 #include "stg/OpenPDU.h"
9 #include "stg/ClosePDU.h"
10 #include "stg/RReqPDU.h"
11 #include "stg/ber_decoder.h"
12 #include "stg/der_encoder.h"
13
14 #include "pen.h"
15 #include "utils.h"
16
17 bool String2OI(const std::string & str, OBJECT_IDENTIFIER_t * oi)
18 {
19 size_t left = 0, pos = 0, arcPos = 0;
20 int arcs[1024];
21 pos = str.find_first_of('.', left);
22 if (pos == 0)
23     {
24     left = 1;
25     pos = str.find_first_of('.', left);
26     }
27 while (pos != std::string::npos)
28     {
29     int arc = 0;
30     if (str2x(str.substr(left, left - pos), arc))
31         {
32         return false;
33         }
34     arcs[arcPos++] = arc;
35     left = pos + 1;
36     pos = str.find_first_of('.', left);
37     }
38 if (left < str.length())
39     {
40     int arc = 0;
41     if (str2x(str.substr(left, left - pos), arc))
42         {
43         return false;
44         }
45     arcs[arcPos++] = arc;
46     }
47 OBJECT_IDENTIFIER_set_arcs(oi, arcs, sizeof(arcs[0]), static_cast<unsigned int>(arcPos));
48 return true;
49 }
50
51 bool SendOpenPDU(int fd)
52 {
53 const char * description = "Stg SMUX Plugin";
54 asn_enc_rval_t error;
55 OpenPDU_t msg;
56
57 memset(&msg, 0, sizeof(msg));
58
59 msg.present = OpenPDU_PR_simple;
60 asn_long2INTEGER(&msg.choice.simple.version, SimpleOpen__version_version_1);
61 if (!String2OI(PEN_PREFIX, &msg.choice.simple.identity))
62     {
63     printfd(__FILE__,
64             "SendOpenPDU() - failed to convert string to OBJECT_IDENTIFIER\n");
65     return false;
66     }
67 OCTET_STRING_fromString(&msg.choice.simple.description, description);
68 OCTET_STRING_fromString(&msg.choice.simple.password, "");
69
70 char buffer[1024];
71 error = der_encode_to_buffer(&asn_DEF_OpenPDU, &msg, buffer, sizeof(buffer));
72
73 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OpenPDU, &msg);
74
75 if (error.encoded == -1)
76     {
77     printfd(__FILE__, "Could not encode OpenPDU (at %s)\n",
78             error.failed_type ? error.failed_type->name : "unknown");
79     return false;
80     }
81 else
82     {
83     if (write(fd, buffer, error.encoded) < 0)
84         {
85         printfd(__FILE__, "Failed to send OpenPDU: %s\n", strerror(errno));
86         return false;
87         }
88     }
89 return true;
90 }
91
92 bool SendClosePDU(int fd)
93 {
94 ClosePDU_t msg;
95
96 memset(&msg, 0, sizeof(msg));
97
98 asn_long2INTEGER(&msg, ClosePDU_goingDown);
99
100 char buffer[1024];
101 asn_enc_rval_t error;
102 error = der_encode_to_buffer(&asn_DEF_ClosePDU, &msg, buffer, sizeof(buffer));
103
104 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_ClosePDU, &msg);
105
106 if (error.encoded == -1)
107     {
108     printfd(__FILE__, "Could not encode ClosePDU (at %s)\n",
109             error.failed_type ? error.failed_type->name : "unknown");
110     return false;
111     }
112 else
113     {
114     if (write(fd, buffer, error.encoded) < 0)
115         {
116         printfd(__FILE__, "Failed to send ClosePDU: %s\n", strerror(errno));
117         return false;
118         }
119     }
120 return true;
121 }
122
123 bool SendRReqPDU(int fd)
124 {
125 int oid[] = {1, 3, 6, 1, 4, 1, 38313, 1};
126 asn_enc_rval_t error;
127 RReqPDU_t msg;
128
129 memset(&msg, 0, sizeof(msg));
130
131 msg.priority = 0;
132 asn_long2INTEGER(&msg.operation, RReqPDU__operation_readOnly);
133 OBJECT_IDENTIFIER_set_arcs(&msg.subtree,
134                            oid,
135                            sizeof(oid[0]),
136                            8);
137
138 char buffer[1024];
139 error = der_encode_to_buffer(&asn_DEF_RReqPDU, &msg, buffer, sizeof(buffer));
140
141 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RReqPDU, &msg);
142
143 if (error.encoded == -1)
144     {
145     printfd(__FILE__, "Could not encode RReqPDU (at %s)\n",
146             error.failed_type ? error.failed_type->name : "unknown");
147     return false;
148     }
149 else
150     {
151     if (write(fd, buffer, error.encoded) < 0)
152         {
153         printfd(__FILE__, "Failed to send RReqPDU: %s\n", strerror(errno));
154         return false;
155         }
156     }
157 return true;
158 }
159
160 SMUX_PDUs_t * RecvSMUXPDUs(int fd)
161 {
162 char buffer[1024];
163 SMUX_PDUs_t * pdus = NULL;
164
165 memset(buffer, 0, sizeof(buffer));
166
167 size_t length = read(fd, buffer, sizeof(buffer));
168 if (length < 1)
169     return NULL;
170 asn_dec_rval_t error;
171 error = ber_decode(0, &asn_DEF_SMUX_PDUs, (void **)&pdus, buffer, length);
172
173 if(error.code != RC_OK)
174     {
175     printfd(__FILE__, "Failed to decode PDUs at byte %ld\n",
176             (long)error.consumed);
177     return NULL;
178     }
179 return pdus;
180 }
181
182 bool SendGetResponsePDU(int fd, GetResponse_PDU_t * getResponse)
183 {
184 asn_enc_rval_t error;
185
186 char buffer[1024];
187 error = der_encode_to_buffer(&asn_DEF_GetResponse_PDU, getResponse, buffer,
188                              sizeof(buffer));
189
190 if (error.encoded == -1)
191     {
192     printfd(__FILE__, "Could not encode GetResponsePDU (at %s)\n",
193             error.failed_type ? error.failed_type->name : "unknown");
194     return false;
195     }
196 else
197     {
198     if (write(fd, buffer, error.encoded) < 0)
199         {
200         printfd(__FILE__, "Failed to send GetResponsePDU: %s\n", strerror(errno));
201         return false;
202         }
203     }
204 return true;
205 }
206
207 bool SendGetResponseErrorPDU(int fd,
208                              const PDU_t * getRequest,
209                              int errorStatus,
210                              int errorIndex)
211 {
212 asn_enc_rval_t error;
213 GetResponse_PDU_t msg;
214
215 memset(&msg, 0, sizeof(msg));
216
217 long id = 0;
218 asn_INTEGER2long(&getRequest->request_id, &id);
219 asn_long2INTEGER(&msg.request_id, id);
220 asn_long2INTEGER(&msg.error_status, errorStatus);
221 asn_long2INTEGER(&msg.error_index, errorIndex);
222
223 char buffer[1024];
224 error = der_encode_to_buffer(&asn_DEF_GetResponse_PDU, &msg, buffer,
225                              sizeof(buffer));
226
227 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_GetResponse_PDU, &msg);
228
229 if (error.encoded == -1)
230     {
231     printfd(__FILE__, "Could not encode GetResponsePDU for error (at %s)\n",
232             error.failed_type ? error.failed_type->name : "unknown");
233     return false;
234     }
235 else
236     {
237     if (write(fd, buffer, error.encoded) < 0)
238         {
239         printfd(__FILE__, "Failed to send GetResponseErrorPDU: %s\n", strerror(errno));
240         return false;
241         }
242     }
243 return true;
244 }