GCC Code Coverage Report
Directory: cvmfs/ Exec Total Coverage
File: cvmfs/authz/helper_util.cc Lines: 0 62 0.0 %
Date: 2019-02-03 02:48:13 Branches: 0 54 0.0 %

Line Branch Exec Source
1
/**
2
 * This file is part of the CernVM File System.
3
 */
4
5
#include "helper_util.h"
6
7
#include <alloca.h>
8
#include <errno.h>
9
#include <stdint.h>
10
#include <unistd.h>
11
12
#include <cassert>
13
#include <cstdio>
14
#include <cstdlib>
15
#include <cstring>
16
17
#include "authz/helper_log.h"
18
#include "json.h"
19
typedef struct json_value JSON;
20
21
#ifdef __APPLE__
22
#define strdupa(s) strcpy(/* NOLINT(runtime/printf) */\
23
  reinterpret_cast<char *>(alloca(strlen((s)) + 1)), (s))
24
#endif
25
26
using namespace std;  // NOLINT
27
28
/**
29
 * Helper binaries are supposed to be called from the cvmfs client, not
30
 * stand-alone.
31
 */
32
void CheckCallContext() {
33
  if (getenv("CVMFS_AUTHZ_HELPER") == NULL) {
34
    printf("This program is supposed to be called from the CernVM-FS client.");
35
    printf("\n");
36
    abort();
37
  }
38
}
39
40
41
void ParseHandshakeInit(const string &msg) {
42
  block_allocator allocator(2048);
43
  char *err_pos; char *err_desc; int err_line;
44
  JSON *json = json_parse(strdupa(msg.c_str()),
45
                          &err_pos, &err_desc, &err_line,
46
                          &allocator);
47
  assert((json != NULL) && (json->first_child != NULL));
48
  json = json->first_child;
49
  assert((string(json->name) == "cvmfs_authz_v1"));
50
  json = json->first_child;
51
  while (json) {
52
    string name(json->name);
53
    if (name == "debug_log") {
54
      SetLogAuthzDebug(string(json->string_value) + ".authz");
55
    } else if (name == "fqrn") {
56
      LogAuthz(kLogAuthzDebug, "fqrn is %s", json->string_value);
57
      SetLogAuthzSyslogPrefix(string(json->string_value));
58
    } else if (name == "syslog_level") {
59
      SetLogAuthzSyslogLevel(json->int_value);
60
    } else if (name == "syslog_facility") {
61
      SetLogAuthzSyslogFacility(json->int_value);
62
    }
63
    json = json->next_sibling;
64
  }
65
}
66
67
68
void ParseRequest(const string &msg) {
69
  block_allocator allocator(2048);
70
  char *err_pos; char *err_desc; int err_line;
71
  JSON *json = json_parse(strdupa(msg.c_str()),
72
                          &err_pos, &err_desc, &err_line,
73
                          &allocator);
74
  assert((json != NULL) && (json->first_child != NULL));
75
  json = json->first_child;
76
  assert((string(json->name) == "cvmfs_authz_v1"));
77
  json = json->first_child;
78
  while (json) {
79
    string name(json->name);
80
    if (name == "msgid") {
81
      if (json->int_value == 4) {  /* kAuthzMsgQuit */
82
        LogAuthz(kLogAuthzDebug, "shut down");
83
        exit(0);
84
      }
85
    }
86
    json = json->next_sibling;
87
  }
88
}
89
90
91
/**
92
 * Get bytes from stdin.
93
 */
94
static void Read(void *buf, size_t nbyte) {
95
  int num_bytes;
96
  do {
97
    num_bytes = read(fileno(stdin), buf, nbyte);
98
  } while ((num_bytes < 0) && (errno == EINTR));
99
  assert((num_bytes >= 0) && (static_cast<size_t>(num_bytes) == nbyte));
100
}
101
102
103
/**
104
 * Reads a complete message from the cvmfs client.
105
 */
106
string ReadMsg() {
107
  uint32_t version;
108
  uint32_t length;
109
  Read(&version, sizeof(version));
110
  assert(version == kProtocolVersion);
111
  Read(&length, sizeof(length));
112
  if (length == 0)
113
    return "";
114
  char *buf = reinterpret_cast<char *>(alloca(length));
115
  Read(buf, length);
116
  return string(buf, length);
117
}
118
119
120
/**
121
 * Send bytes to stdout.
122
 */
123
static void Write(const void *buf, size_t nbyte) {
124
  int num_bytes;
125
  do {
126
    num_bytes = write(fileno(stdout), buf, nbyte);
127
  } while ((num_bytes < 0) && (errno == EINTR));
128
  assert((num_bytes >= 0) && (static_cast<size_t>(num_bytes) == nbyte));
129
}
130
131
132
/**
133
 * Sends a (JSON formatted) message back to the cvmfs client.
134
 */
135
void WriteMsg(const string &msg) {
136
  struct {
137
    uint32_t version;
138
    uint32_t length;
139
  } header;
140
  header.version = kProtocolVersion;
141
  header.length = msg.length();
142
  Write(&header, sizeof(header));
143
  Write(msg.data(), header.length);
144
}