1 /*
2    BAREOS® - Backup Archiving REcovery Open Sourced
3 
4    Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
5    Copyright (C) 2016-2018 Bareos GmbH & Co. KG
6 
7    This program is Free Software; you can redistribute it and/or
8    modify it under the terms of version three of the GNU Affero General Public
9    License as published by the Free Software Foundation and included
10    in the file LICENSE.
11 
12    This program is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15    Affero General Public License for more details.
16 
17    You should have received a copy of the GNU Affero General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20    02110-1301, USA.
21 */
22 /*
23  * Kern Sibbald, May MM
24  */
25 /**
26  * @file
27  * BAREOS Sock Class definition
28  * Note, the old non-class code is in bnet.c, and the
29  * new class code associated with this file is in bsock.c
30  *
31  * Zero message_length from other end indicates soft eof (usually
32  * end of some binary data stream, but not end of conversation).
33  *
34  * Negative message_length, is special "signal" (no data follows).
35  * See below for SIGNAL codes.
36  */
37 
38 #ifndef BAREOS_LIB_BSOCK_H_
39 #define BAREOS_LIB_BSOCK_H_
40 
41 #include <include/bareos.h>
42 #include <mutex>
43 #include <functional>
44 #include <cassert>
45 #include "lib/address_conf.h"
46 #include "lib/bnet_network_dump.h"
47 #include "lib/tls.h"
48 #include "lib/s_password.h"
49 #include "lib/tls_conf.h"
50 #include "include/version_numbers.h"
51 
52 struct btimer_t; /* forward reference */
53 class BareosSocket;
54 class Tls;
55 class BStringList;
56 class QualifiedResourceNameTypeConverter;
57 class dlist;
58 btimer_t* StartBsockTimer(BareosSocket* bs, uint32_t wait);
59 void StopBsockTimer(btimer_t* wid);
60 
61 class BareosSocket {
62   /*
63    * Note, keep this public part before the private otherwise
64    *  bat breaks on some systems such as RedHat.
65    */
66  public:
67   int fd_;                     /* Socket file descriptor */
68   uint64_t read_seqno;         /* Read sequence number */
69   POOLMEM* msg;                /* Message pool buffer */
70   POOLMEM* errmsg;             /* Edited error message */
71   int spool_fd_;               /* Spooling file */
72   IPADDR* src_addr;            /* IP address to source connections from */
73   uint32_t in_msg_no;          /* Input message number */
74   uint32_t out_msg_no;         /* Output message number */
75   int32_t message_length;      /* Message length */
76   volatile time_t timer_start; /* Time started read/write */
77   int b_errno;                 /* BareosSocket errno */
78   int blocking_;       /* Blocking state (0 = nonblocking, 1 = blocking) */
79   volatile int errors; /* Incremented for each error on socket */
80   volatile bool suppress_error_msgs_; /* Set to suppress error messages */
81   int sleep_time_after_authentication_error;
82 
83   struct sockaddr client_addr;  /* Client's IP address */
84   struct sockaddr_in peer_addr; /* Peer's IP address */
SetTlsEstablished()85   void SetTlsEstablished() { tls_established_ = true; }
TlsEstablished()86   bool TlsEstablished() const { return tls_established_; }
87   std::shared_ptr<Tls> tls_conn;      /* Associated tls connection */
88   std::unique_ptr<Tls> tls_conn_init; /* during initialization */
89   BareosVersionNumber connected_daemon_version_;
90 
91  protected:
92   JobControlRecord* jcr_; /* JobControlRecord or NULL for error msgs */
93   std::shared_ptr<std::mutex> mutex_;
94   char* who_;            /* Name of daemon to which we are talking */
95   char* host_;           /* Host name/IP */
96   int port_;             /* Desired port */
97   btimer_t* tid_;        /* Timer id */
98   boffset_t data_end_;   /* Offset of last valid data written */
99   int32_t FileIndex_;    /* Last valid attr spool FI */
100   bool timed_out_;       /* Timed out in read/write */
101   bool terminated_;      /* Set when BNET_TERMINATE arrives */
102   bool cloned_;          /* Set if cloned BareosSocket */
103   bool spool_;           /* Set for spooling */
104   bool use_bursting_;    /* Set to use bandwidth bursting */
105   bool use_keepalive_;   /* Set to use keepalive on the socket */
106   int64_t bwlimit_;      /* Set to limit bandwidth */
107   int64_t nb_bytes_;     /* Bytes sent/recv since the last tick */
108   btime_t last_tick_;    /* Last tick used by bwlimit */
109   bool tls_established_; /* is true when tls connection is established */
110   std::unique_ptr<BnetDump> bnet_dump_;
111 
112   virtual void FinInit(JobControlRecord* jcr,
113                        int sockfd,
114                        const char* who,
115                        const char* host,
116                        int port,
117                        struct sockaddr* lclient_addr) = 0;
118   virtual bool open(JobControlRecord* jcr,
119                     const char* name,
120                     const char* host,
121                     char* service,
122                     int port,
123                     utime_t heart_beat,
124                     int* fatal) = 0;
125 
126  private:
127   bool TwoWayAuthenticate(JobControlRecord* jcr,
128                           const std::string own_qualified_name,
129                           const char* identity,
130                           s_password& password,
131                           TlsResource* tls_resource,
132                           bool initiated_by_remote);
133   bool DoTlsHandshakeWithClient(TlsConfigCert* local_tls_cert,
134                                 JobControlRecord* jcr);
135   bool DoTlsHandshakeWithServer(TlsConfigCert* local_tls_cert,
136                                 const char* identity,
137                                 const char* password,
138                                 JobControlRecord* jcr);
139   void ParameterizeTlsCert(Tls* tls_conn, TlsResource* tls_resource);
SetBnetDump(std::unique_ptr<BnetDump> && bnet_dump)140   void SetBnetDump(std::unique_ptr<BnetDump>&& bnet_dump)
141   {
142     // do not set twice
143     assert(!bnet_dump_);
144     bnet_dump_ = std::move(bnet_dump);
145   }
146 
147  public:
148   BareosSocket();
149   BareosSocket(const BareosSocket& other);
150   virtual ~BareosSocket();
151 
152   /* Methods -- in bsock.c */
153   //  void free_bsock();
154   void CloseTlsConnectionAndFreeMemory();
155   virtual BareosSocket* clone() = 0;
156   virtual bool connect(JobControlRecord* jcr,
157                        int retry_interval,
158                        utime_t max_retry_time,
159                        utime_t heart_beat,
160                        const char* name,
161                        const char* host,
162                        char* service,
163                        int port,
164                        bool verbose) = 0;
165   virtual int32_t recv() = 0;
166   virtual bool send() = 0;
167   virtual int32_t read_nbytes(char* ptr, int32_t nbytes) = 0;
168   virtual int32_t write_nbytes(char* ptr, int32_t nbytes) = 0;
169   virtual void close() = 0;   /* close connection and destroy packet */
170   virtual void destroy() = 0; /* destroy socket packet */
171   virtual int GetPeer(char* buf, socklen_t buflen) = 0;
172   virtual bool SetBufferSize(uint32_t size, int rw) = 0;
173   virtual int SetNonblocking() = 0;
174   virtual int SetBlocking() = 0;
175   virtual void RestoreBlocking(int flags) = 0;
176   virtual bool ConnectionReceivedTerminateSignal() = 0;
177   /*
178    * Returns: 1 if data available, 0 if timeout, -1 if error
179    */
180   virtual int WaitData(int sec, int usec = 0) = 0;
181   virtual int WaitDataIntr(int sec, int usec = 0) = 0;
182   bool fsend(const char*, ...);
183   bool send(const char* msg_in, uint32_t nbytes);
184   void SetKillable(bool killable);
185   bool signal(int signal);
186   const char* bstrerror(); /* last error on socket */
187   bool despool(void UpdateAttrSpoolSize(ssize_t size), ssize_t tsize);
188   bool ConsoleAuthenticateWithDirector(JobControlRecord* jcr,
189                                        const char* name,
190                                        s_password& password,
191                                        TlsResource* tls_resource,
192                                        const std::string& own_qualified_name,
193                                        BStringList& response_args,
194                                        uint32_t& response_id);
195   bool ParameterizeAndInitTlsConnection(TlsResource* tls_resource,
196                                         const char* identity,
197                                         const char* password,
198                                         bool initiated_by_remote);
199   bool ParameterizeAndInitTlsConnectionAsAServer(ConfigurationParser* config);
200   bool DoTlsHandshake(TlsPolicy remote_tls_policy,
201                       TlsResource* tls_resource,
202                       bool initiated_by_remote,
203                       const char* identity,
204                       const char* password,
205                       JobControlRecord* jcr);
206   bool DoTlsHandshakeAsAServer(ConfigurationParser* config,
207                                JobControlRecord* jcr = nullptr);
208   bool SetLocking();   /* in bsock.c */
209   void ClearLocking(); /* in bsock.c */
210   void SetSourceAddress(dlist* src_addr_list);
211   void ControlBwlimit(int bytes); /* in bsock.c */
212   bool EvaluateCleartextBareosHello(bool& cleartext,
213                                     std::string& client_name_out,
214                                     std::string& r_code_str_out,
215                                     BareosVersionNumber& version_out) const;
216   void OutputCipherMessageString(std::function<void(const char*)>);
217   void GetCipherMessageString(std::string& str) const;
218   bool ReceiveAndEvaluateResponseMessage(uint32_t& id_out,
219                                          BStringList& args_out);
220   bool FormatAndSendResponseMessage(uint32_t id,
221                                     const BStringList& list_of_agruments);
222   bool FormatAndSendResponseMessage(uint32_t id, const std::string& str);
223 
224   bool AuthenticateOutboundConnection(JobControlRecord* jcr,
225                                       const std::string own_qualified_name,
226                                       const char* identity,
227                                       s_password& password,
228                                       TlsResource* tls_resource);
229 
230   bool AuthenticateInboundConnection(JobControlRecord* jcr,
231                                      ConfigurationParser* my_config,
232                                      const char* name,
233                                      s_password& password,
234                                      TlsResource* tls_resource);
235 
SetJcr(JobControlRecord * jcr)236   void SetJcr(JobControlRecord* jcr) { jcr_ = jcr; }
SetWho(char * who)237   void SetWho(char* who) { who_ = who; }
SetHost(char * host)238   void SetHost(char* host) { host_ = host; }
SetPort(int port)239   void SetPort(int port) { port_ = port; }
who()240   char* who() { return who_; }
host()241   char* host() { return host_; }
port()242   int port() { return port_; }
jcr()243   JobControlRecord* jcr() { return jcr_; }
get_jcr()244   JobControlRecord* get_jcr() { return jcr_; }
IsSpooling()245   bool IsSpooling() { return spool_; }
IsTerminated()246   bool IsTerminated() { return terminated_; }
IsTimedOut()247   bool IsTimedOut() { return timed_out_; }
IsStop()248   bool IsStop() { return errors || IsTerminated(); }
IsError()249   bool IsError()
250   {
251     errno = b_errno;
252     return errors;
253   }
SetDataEnd(int32_t FileIndex)254   void SetDataEnd(int32_t FileIndex)
255   {
256     if (spool_ && FileIndex > FileIndex_) {
257       FileIndex_ = FileIndex - 1;
258       data_end_ = lseek(spool_fd_, 0, SEEK_CUR);
259     }
260   }
get_data_end()261   boffset_t get_data_end() { return data_end_; }
get_FileIndex()262   int32_t get_FileIndex() { return FileIndex_; }
SetBwlimit(int64_t maxspeed)263   void SetBwlimit(int64_t maxspeed) { bwlimit_ = maxspeed; }
UseBwlimit()264   bool UseBwlimit() { return bwlimit_ > 0; }
SetBwlimitBursting()265   void SetBwlimitBursting() { use_bursting_ = true; }
clear_bwlimit_bursting()266   void clear_bwlimit_bursting() { use_bursting_ = false; }
SetKeepalive()267   void SetKeepalive() { use_keepalive_ = true; }
ClearKeepalive()268   void ClearKeepalive() { use_keepalive_ = false; }
SetSpooling()269   void SetSpooling() { spool_ = true; }
ClearSpooling()270   void ClearSpooling() { spool_ = false; }
SetTimedOut()271   void SetTimedOut() { timed_out_ = true; }
ClearTimedOut()272   void ClearTimedOut() { timed_out_ = false; }
SetTerminated()273   void SetTerminated() { terminated_ = true; }
StartTimer(int sec)274   void StartTimer(int sec) { tid_ = StartBsockTimer(this, sec); }
StopTimer()275   void StopTimer() { StopBsockTimer(tid_); }
276   void LockMutex();
277   void UnlockMutex();
278   void InitBnetDump(std::string own_qualified_name);
279   void SetBnetDumpDestinationQualifiedName(
280       std::string destination_qualified_name);
IsBnetDumpEnabled()281   bool IsBnetDumpEnabled() const { return bnet_dump_.get() != nullptr; }
282 };
283 
284 /**
285  *  Signal definitions for use in BnetSig()
286  *  Note! These must be negative.  There are signals that are generated
287  *   by the bsock software not by the OS ...
288  */
289 enum
290 {
291   BNET_EOD = -1,           /* End of data stream, new data may follow */
292   BNET_EOD_POLL = -2,      /* End of data and poll all in one */
293   BNET_STATUS = -3,        /* Send full status */
294   BNET_TERMINATE = -4,     /* Conversation terminated, doing close() */
295   BNET_POLL = -5,          /* Poll request, I'm hanging on a read */
296   BNET_HEARTBEAT = -6,     /* Heartbeat Response requested */
297   BNET_HB_RESPONSE = -7,   /* Only response permited to HB */
298   BNET_xxxxxxPROMPT = -8,  /* No longer used -- Prompt for subcommand */
299   BNET_BTIME = -9,         /* Send UTC btime */
300   BNET_BREAK = -10,        /* Stop current command -- ctl-c */
301   BNET_START_SELECT = -11, /* Start of a selection list */
302   BNET_END_SELECT = -12,   /* End of a select list */
303   BNET_INVALID_CMD = -13,  /* Invalid command sent */
304   BNET_CMD_FAILED = -14,   /* Command failed */
305   BNET_CMD_OK = -15,       /* Command succeeded */
306   BNET_CMD_BEGIN = -16,    /* Start command execution */
307   BNET_MSGS_PENDING = -17, /* Messages pending */
308   BNET_MAIN_PROMPT = -18,  /* Server ready and waiting */
309   BNET_SELECT_INPUT = -19, /* Return selection input */
310   BNET_WARNING_MSG = -20,  /* Warning message */
311   BNET_ERROR_MSG = -21,    /* Error message -- command failed */
312   BNET_INFO_MSG = -22,     /* Info message -- status line */
313   BNET_RUN_CMD = -23,      /* Run command follows */
314   BNET_YESNO = -24,        /* Request yes no response */
315   BNET_START_RTREE = -25,  /* Start restore tree mode */
316   BNET_END_RTREE = -26,    /* End restore tree mode */
317   BNET_SUB_PROMPT = -27,   /* Indicate we are at a subprompt */
318   BNET_TEXT_INPUT = -28    /* Get text input from user */
319 };
320 
321 #define BNET_SETBUF_READ 1  /* Arg for BnetSetBufferSize */
322 #define BNET_SETBUF_WRITE 2 /* Arg for BnetSetBufferSize */
323 
324 /**
325  * Return status from BnetRecv()
326  * Note, the HARDEOF and ERROR refer to comm status/problems
327  *  rather than the BNET_xxx above, which are software signals.
328  */
329 enum
330 {
331   BNET_SIGNAL = -1,
332   BNET_HARDEOF = -2,
333   BNET_ERROR = -3
334 };
335 
336 #endif /* BAREOS_LIB_BSOCK_H_ */
337