1 /*
2   Copyright 2021 Northern.tech AS
3 
4   This file is part of CFEngine 3 - written and maintained by Northern.tech AS.
5 
6   This program is free software; you can redistribute it and/or modify it
7   under the terms of the GNU General Public License as published by the
8   Free Software Foundation; version 3.
9 
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14 
15   You should have received a copy of the GNU General Public License
16   along with this program; if not, write to the Free Software
17   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
18 
19   To the extent this program is licensed as part of the Enterprise
20   versions of CFEngine, the applicable Commercial Open Source License
21   (COSL) may apply to this file if you as a licensee so wish it. See
22   included file COSL.txt.
23 */
24 
25 #include <alloc.h>
26 #include <cfnet.h>
27 #include <refcount.h>
28 #include <connection_info.h>
29 
30 
ConnectionInfoNew(void)31 ConnectionInfo *ConnectionInfoNew(void)
32 {
33     struct ConnectionInfo *info = xcalloc(1, sizeof(struct ConnectionInfo));
34     info->sd = SOCKET_INVALID;
35 
36     return info;
37 }
38 
ConnectionInfoDestroy(ConnectionInfo ** info)39 void ConnectionInfoDestroy(ConnectionInfo **info)
40 {
41     if (!info || !*info)
42     {
43         return;
44     }
45     /* Destroy everything */
46     if ((*info)->ssl)
47     {
48         SSL_free((*info)->ssl);
49     }
50     KeyDestroy(&(*info)->remote_key);
51     free(*info);
52     *info = NULL;
53 }
54 
ConnectionInfoProtocolVersion(const ConnectionInfo * info)55 ProtocolVersion ConnectionInfoProtocolVersion(const ConnectionInfo *info)
56 {
57     assert(info != NULL);
58 
59     return info ? info->protocol : CF_PROTOCOL_UNDEFINED;
60 }
61 
ConnectionInfoSetProtocolVersion(ConnectionInfo * info,ProtocolVersion version)62 void ConnectionInfoSetProtocolVersion(ConnectionInfo *info, ProtocolVersion version)
63 {
64     assert(info != NULL);
65 
66     if (info ==  NULL)
67     {
68         return;
69     }
70     switch (version)
71     {
72     case CF_PROTOCOL_UNDEFINED:
73     case CF_PROTOCOL_CLASSIC:
74     case CF_PROTOCOL_TLS:
75         info->protocol = version;
76         break;
77     default:
78         break;
79     }
80 }
81 
ConnectionInfoSocket(const ConnectionInfo * info)82 int ConnectionInfoSocket(const ConnectionInfo *info)
83 {
84     assert(info != NULL);
85 
86     return info ? info->sd : -1;
87 }
88 
ConnectionInfoSetSocket(ConnectionInfo * info,int s)89 void ConnectionInfoSetSocket(ConnectionInfo *info, int s)
90 {
91     assert(info != NULL);
92 
93     if (info == NULL)
94     {
95         return;
96     }
97     info->sd = s;
98 }
99 
ConnectionInfoSSL(const ConnectionInfo * info)100 SSL *ConnectionInfoSSL(const ConnectionInfo *info)
101 {
102     assert(info != NULL);
103 
104     return info ? info->ssl : NULL;
105 }
106 
ConnectionInfoSetSSL(ConnectionInfo * info,SSL * ssl)107 void ConnectionInfoSetSSL(ConnectionInfo *info, SSL *ssl)
108 {
109     assert(info != NULL);
110 
111     if (info == NULL)
112     {
113         return;
114     }
115     info->ssl = ssl;
116 }
117 
ConnectionInfoKey(const ConnectionInfo * info)118 const Key *ConnectionInfoKey(const ConnectionInfo *info)
119 {
120     assert(info != NULL);
121 
122     const Key *key = info ? info->remote_key : NULL;
123     return key;
124 }
125 
ConnectionInfoSetKey(ConnectionInfo * info,Key * key)126 void ConnectionInfoSetKey(ConnectionInfo *info, Key *key)
127 {
128     assert(info != NULL);
129 
130     if (info == NULL)
131     {
132         return;
133     }
134     /* The key can be assigned only once on a session */
135     if (info->remote_key)
136     {
137         return;
138     }
139     if (!key)
140     {
141         return;
142     }
143     info->remote_key = key;
144 }
145 
ConnectionInfoBinaryKeyHash(ConnectionInfo * info,unsigned int * length)146 const unsigned char *ConnectionInfoBinaryKeyHash(ConnectionInfo *info, unsigned int *length)
147 {
148     assert(info != NULL);
149 
150     if (info == NULL)
151     {
152         return NULL;
153     }
154     Key *connection_key = info->remote_key;
155     unsigned int real_length = 0;
156     const unsigned char *binary = KeyBinaryHash(connection_key, &real_length);
157     if (length)
158     {
159         *length = real_length;
160     }
161     return binary;
162 }
163 
ConnectionInfoPrintableKeyHash(ConnectionInfo * info)164 const char *ConnectionInfoPrintableKeyHash(ConnectionInfo *info)
165 {
166     assert(info != NULL);
167 
168     return info ? KeyPrintableHash(info->remote_key) : NULL;
169 }
170