LCOV - code coverage report
Current view: top level - src/server - auth.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 87 87 100.0 %
Date: 2016-07-02 Functions: 4 4 100.0 %

          Line data    Source code
       1             : #include "../burp.h"
       2             : #include "../alloc.h"
       3             : #include "../asfd.h"
       4             : #include "../async.h"
       5             : #include "../cmd.h"
       6             : #include "../conf.h"
       7             : #include "../conffile.h"
       8             : #include "../handy.h"
       9             : #include "../iobuf.h"
      10             : #include "../log.h"
      11             : 
      12             : #ifndef UTEST
      13             : static
      14             : #endif
      15           8 : int check_passwd(const char *passwd, const char *plain_text)
      16             : {
      17             : #ifdef HAVE_CRYPT
      18           8 :         const char *encrypted=NULL;
      19           8 :         if(!plain_text || !passwd || strlen(passwd)<13)
      20             :                 return 0;
      21             : 
      22           5 :         encrypted=crypt(plain_text, passwd);
      23           5 :         return encrypted && !strcmp(encrypted, passwd);
      24             : #endif // HAVE_CRYPT
      25             :         logp("Server compiled without crypt support - cannot use passwd option\n");
      26             :         return -1;
      27             : }
      28             : 
      29           7 : static int check_client_and_password(struct conf **globalcs,
      30             :         const char *password, struct conf **cconfs)
      31             : {
      32             :         const char *cname;
      33             :         int password_check;
      34             :         // Cannot load it until here, because we need to have the name of the
      35             :         // client.
      36           7 :         if(conf_load_clientconfdir(globalcs, cconfs)) return -1;
      37             : 
      38           7 :         cname=get_string(cconfs[OPT_CNAME]);
      39           7 :         password_check=get_int(cconfs[OPT_PASSWORD_CHECK]);
      40             : 
      41           7 :         if(!get_string(cconfs[OPT_SSL_PEER_CN]))
      42             :         {
      43           7 :                 logp("ssl_peer_cn unset");
      44           7 :                 if(cname)
      45             :                 {
      46           7 :                         logp("Falling back to using '%s'\n", cname);
      47           7 :                         if(set_string(cconfs[OPT_SSL_PEER_CN], cname))
      48             :                                 return -1;
      49             :                 }
      50             :         }
      51             : 
      52           7 :         cname=get_string(cconfs[OPT_CNAME]);
      53             : 
      54           7 :         if(password_check)
      55             :         {
      56           7 :                 const char *conf_passwd=get_string(cconfs[OPT_PASSWD]);
      57           7 :                 const char *conf_password=get_string(cconfs[OPT_PASSWORD]);
      58           7 :                 if(!conf_password && !conf_passwd)
      59             :                 {
      60           1 :                         logp("password rejected for client %s\n", cname);
      61           1 :                         return -1;
      62             :                 }
      63             :                 // check against plain text
      64           6 :                 if(conf_password && strcmp(conf_password, password))
      65             :                 {
      66           1 :                         logp("password rejected for client %s\n", cname);
      67           1 :                         return -1;
      68             :                 }
      69             :                 // check against encypted passwd
      70           5 :                 if(conf_passwd && !check_passwd(conf_passwd, password))
      71             :                 {
      72           1 :                         logp("password rejected for client %s\n", cname);
      73           1 :                         return -1;
      74             :                 }
      75             :         }
      76             : 
      77           4 :         if(!get_strlist(cconfs[OPT_KEEP]))
      78             :         {
      79             :                 logp("%s: you cannot set the keep value for a client to 0!\n",
      80           1 :                         cname);
      81           1 :                 return -1;
      82             :         }
      83             :         return 0;
      84             : }
      85             : 
      86           3 : void version_warn(struct asfd *asfd, struct conf **confs, struct conf **cconfs)
      87             : {
      88           3 :         const char *cname=get_string(cconfs[OPT_CNAME]);
      89           3 :         const char *peer_version=get_string(cconfs[OPT_PEER_VERSION]);
      90           3 :         if(!peer_version || strcmp(peer_version, VERSION))
      91             :         {
      92           2 :                 char msg[256]="";
      93             : 
      94           2 :                 if(!peer_version || !*peer_version)
      95           1 :                         snprintf(msg, sizeof(msg), "Client '%s' has an unknown version. Please upgrade.", cname?cname:"unknown");
      96             :                 else
      97           1 :                         snprintf(msg, sizeof(msg), "Client '%s' version '%s' does not match server version '%s'. An upgrade is recommended.", cname?cname:"unknown", peer_version, VERSION);
      98           2 :                 if(confs) logw(asfd, get_cntr(confs), "%s\n", msg);
      99           2 :                 logp("WARNING: %s\n", msg);
     100             :         }
     101           3 : }
     102             : 
     103          11 : int authorise_server(struct asfd *asfd,
     104             :         struct conf **globalcs, struct conf **cconfs)
     105             : {
     106          11 :         int ret=-1;
     107          11 :         char *cp=NULL;
     108          11 :         char *password=NULL;
     109          11 :         char whoareyou[256]="";
     110          11 :         struct iobuf *rbuf=asfd->rbuf;
     111          11 :         const char *peer_version=NULL;
     112          11 :         if(asfd->read(asfd))
     113             :         {
     114           1 :                 logp("unable to read initial message\n");
     115           1 :                 goto end;
     116             :         }
     117          10 :         if(rbuf->cmd!=CMD_GEN || strncmp_w(rbuf->buf, "hello"))
     118             :         {
     119           1 :                 iobuf_log_unexpected(rbuf, __func__);
     120           1 :                 goto end;
     121             :         }
     122             :         // String may look like...
     123             :         // "hello"
     124             :         // "hello:(version)"
     125             :         // (version) is a version number
     126          18 :         if((cp=strchr(rbuf->buf, ':')))
     127             :         {
     128           8 :                 cp++;
     129           8 :                 if(cp && set_string(cconfs[OPT_PEER_VERSION], cp))
     130             :                         goto end;
     131             :         }
     132           9 :         iobuf_free_content(rbuf);
     133             : 
     134             :         snprintf(whoareyou, sizeof(whoareyou), "whoareyou");
     135           9 :         peer_version=get_string(cconfs[OPT_PEER_VERSION]);
     136           9 :         if(peer_version)
     137             :         {
     138           8 :                 long min_ver=0;
     139           8 :                 long cli_ver=0;
     140           8 :                 if((min_ver=version_to_long("1.3.2"))<0
     141           8 :                   || (cli_ver=version_to_long(peer_version))<0)
     142             :                         return -1;
     143             :                 // Stick the server version on the end of the whoareyou string.
     144             :                 // if the client version is recent enough.
     145           8 :                 if(min_ver<=cli_ver)
     146             :                  snprintf(whoareyou, sizeof(whoareyou),
     147             :                         "whoareyou:%s", VERSION);
     148             :         }
     149             : 
     150          18 :         if(asfd->write_str(asfd, CMD_GEN, whoareyou)
     151           9 :           || asfd->read(asfd))
     152             :         {
     153           1 :                 logp("unable to get client name\n");
     154           1 :                 goto end;
     155             :         }
     156           8 :         if(set_string(cconfs[OPT_CNAME], rbuf->buf))
     157             :                 goto end;
     158           8 :         iobuf_free_content(rbuf);
     159             : 
     160          16 :         if(asfd->write_str(asfd, CMD_GEN, "okpassword")
     161           8 :           || asfd->read(asfd))
     162             :         {
     163             :                 logp("unable to get password for client %s\n",
     164           1 :                         get_string(cconfs[OPT_CNAME]));
     165           1 :                 goto end;
     166             :         }
     167           7 :         password=rbuf->buf;
     168           7 :         iobuf_init(rbuf);
     169             : 
     170           7 :         if(check_client_and_password(globalcs, password, cconfs))
     171             :                 goto end;
     172             : 
     173           3 :         if(get_int(cconfs[OPT_VERSION_WARN]))
     174           3 :                 version_warn(asfd, globalcs, cconfs);
     175             : 
     176             :         logp("auth ok for: %s%s\n", get_string(cconfs[OPT_CNAME]),
     177           3 :                 get_int(cconfs[OPT_PASSWORD_CHECK])?
     178           3 :                         "":" (no password needed)");
     179             : 
     180           3 :         if(asfd->write_str(asfd, CMD_GEN, "ok"))
     181             :                 goto end;
     182             : 
     183           3 :         ret=0;
     184             : end:
     185          11 :         iobuf_free_content(rbuf);
     186          11 :         free_w(&password);
     187          11 :         return ret;
     188             : }

Generated by: LCOV version 1.10