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