/mandos/release

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/release

« back to all changes in this revision

Viewing changes to plugins.d/password-prompt.c

First version of a somewhat complete D-Bus server interface.  Also
change user/group name to "_mandos".

* debian/mandos.postinst: Rename old "mandos" user and group to
                          "_mandos"; create "_mandos" user and group
                          if none exist.
* debian/mandos-client.postinst: - '' -

* initramfs-tools-hook: Try "_mandos" before "mandos" as user and
                        group name.

* mandos (_datetime_to_dbus_struct): New; was previously local.
  (Client.started): Renamed to "last_started".  All users changed.
  (Client.started): New; boolean.
  (Client.dbus_object_path): New.
  (Client.check_command): Renamed to "checker_command".  All users
                          changed.
  (Client.__init__): Set and use "self.dbus_object_path".  Set
                     "self.started".
  (Client.start): Update "self.started".  Emit "self.PropertyChanged"
                  signals for both "started" and "last_started".
  (Client.stop): Update "self.started".  Emit "self.PropertyChanged"
                 signal for "started".
  (Client.checker_callback): Take additional "command" argument.  All
                             callers changed. Emit
                             "self.PropertyChanged" signal.
  (Client.bump_timeout): Emit "self.PropertyChanged" signal for
                         "last_checked_ok".
  (Client.start_checker): Emit "self.PropertyChanged" signal for
                          "checker_running".
  (Client.stop_checker): Emit "self.PropertyChanged" signal for
                         "checker_running".
  (Client.still_valid): Bug fix: use "getattr(self, started, False)"
                        instead of "self.started" in case this client
                        object is so new that the "started" attribute
                        has not been created yet.
  (Client.IntervalChanged, Client.CheckerIsRunning, Client.GetChecker,
  Client.GetCreated, Client.GetFingerprint, Client.GetHost,
  Client.GetInterval, Client.GetName, Client.GetStarted,
  Client.GetTimeout, Client.StateChanged, Client.TimeoutChanged):
  Removed; all callers changed.
  (Client.CheckerCompleted): Add "condition" and "command" arguments.
                             All callers changed.
  (Client.GetAllProperties, Client.PropertyChanged): New.
  (Client.StillValid): Renamed to "IsStillValid".
  (Client.StartChecker): Changed to its own function to avoid the
                         return value from "Client.start_checker()".
  (Client.Stop): Changed to its own function to avoid the return value
                 from "Client.stop()".
  (main): Try "_mandos" before "mandos" as user and group name.
          Removed inner function "remove_from_clients".  New inner
          class "MandosServer".

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*  -*- coding: utf-8 -*- */
2
2
/*
3
 
 * Password-prompt - Read a password from the terminal and print it
 
3
 * Passprompt - Read a password from the terminal and print it
4
4
 * 
5
 
 * Copyright © 2008,2009 Teddy Hogeborn
6
 
 * Copyright © 2008,2009 Björn Påhlsson
 
5
 * Copyright © 2008 Teddy Hogeborn
 
6
 * Copyright © 2008 Björn Påhlsson
7
7
 * 
8
8
 * This program is free software: you can redistribute it and/or
9
9
 * modify it under the terms of the GNU General Public License as
51
51
                                   ARGP_KEY_ARG, ARGP_KEY_END,
52
52
                                   ARGP_ERR_UNKNOWN */
53
53
 
54
 
volatile sig_atomic_t quit_now = 0;
 
54
volatile bool quit_now = false;
55
55
bool debug = false;
56
56
const char *argp_program_version = "password-prompt " VERSION;
57
57
const char *argp_program_bug_address = "<mandos@fukt.bsnet.se>";
58
58
 
59
59
static void termination_handler(__attribute__((unused))int signum){
60
 
  quit_now = 1;
 
60
  quit_now = true;
61
61
}
62
62
 
63
63
int main(int argc, char **argv){
79
79
        .doc = "Debug mode", .group = 3 },
80
80
      { .name = NULL }
81
81
    };
82
 
    
83
 
    error_t parse_opt (int key, char *arg, struct argp_state *state){
84
 
      switch (key){
 
82
  
 
83
    error_t parse_opt (int key, char *arg, struct argp_state *state) {
 
84
      /* Get the INPUT argument from `argp_parse', which we know is a
 
85
         pointer to our plugin list pointer. */
 
86
      switch (key) {
85
87
      case 'p':
86
88
        prefix = arg;
87
89
        break;
89
91
        debug = true;
90
92
        break;
91
93
      case ARGP_KEY_ARG:
92
 
        argp_usage(state);
 
94
        argp_usage (state);
93
95
        break;
94
96
      case ARGP_KEY_END:
95
97
        break;
98
100
      }
99
101
      return 0;
100
102
    }
101
 
    
 
103
  
102
104
    struct argp argp = { .options = options, .parser = parse_opt,
103
105
                         .args_doc = "",
104
106
                         .doc = "Mandos password-prompt -- Read and"
105
107
                         " output a password" };
106
 
    ret = argp_parse(&argp, argc, argv, 0, 0, NULL);
107
 
    if(ret == ARGP_ERR_UNKNOWN){
 
108
    ret = argp_parse (&argp, argc, argv, 0, 0, NULL);
 
109
    if (ret == ARGP_ERR_UNKNOWN){
108
110
      fprintf(stderr, "Unknown error while parsing arguments\n");
109
111
      return EXIT_FAILURE;
110
112
    }
111
113
  }
112
 
  
113
 
  if(debug){
 
114
    
 
115
  if (debug){
114
116
    fprintf(stderr, "Starting %s\n", argv[0]);
115
117
  }
116
 
  if(debug){
 
118
  if (debug){
117
119
    fprintf(stderr, "Storing current terminal attributes\n");
118
120
  }
119
121
  
120
 
  if(tcgetattr(STDIN_FILENO, &t_old) != 0){
 
122
  if (tcgetattr(STDIN_FILENO, &t_old) != 0){
121
123
    perror("tcgetattr");
122
124
    return EXIT_FAILURE;
123
125
  }
131
133
    perror("sigaction");
132
134
    return EXIT_FAILURE;
133
135
  }
134
 
  if(old_action.sa_handler != SIG_IGN){
 
136
  if (old_action.sa_handler != SIG_IGN){
135
137
    ret = sigaction(SIGINT, &new_action, NULL);
136
138
    if(ret == -1){
137
139
      perror("sigaction");
143
145
    perror("sigaction");
144
146
    return EXIT_FAILURE;
145
147
  }
146
 
  if(old_action.sa_handler != SIG_IGN){
 
148
  if (old_action.sa_handler != SIG_IGN){
147
149
    ret = sigaction(SIGHUP, &new_action, NULL);
148
150
    if(ret == -1){
149
151
      perror("sigaction");
155
157
    perror("sigaction");
156
158
    return EXIT_FAILURE;
157
159
  }
158
 
  if(old_action.sa_handler != SIG_IGN){
 
160
  if (old_action.sa_handler != SIG_IGN){
159
161
    ret = sigaction(SIGTERM, &new_action, NULL);
160
162
    if(ret == -1){
161
163
      perror("sigaction");
164
166
  }
165
167
  
166
168
  
167
 
  if(debug){
 
169
  if (debug){
168
170
    fprintf(stderr, "Removing echo flag from terminal attributes\n");
169
171
  }
170
172
  
171
173
  t_new = t_old;
172
174
  t_new.c_lflag &= ~ECHO;
173
 
  if(tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_new) != 0){
 
175
  if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_new) != 0){
174
176
    perror("tcsetattr-echo");
175
177
    return EXIT_FAILURE;
176
178
  }
177
179
 
178
 
  if(debug){
 
180
  if (debug){
179
181
    fprintf(stderr, "Waiting for input from stdin \n");
180
182
  }
181
183
  while(true){
182
 
    if(quit_now){
 
184
    if (quit_now){
183
185
      if(debug){
184
186
        fprintf(stderr, "Interrupted by signal, exiting.\n");
185
187
      }
194
196
      const char *cryptsource = getenv("cryptsource");
195
197
      const char *crypttarget = getenv("crypttarget");
196
198
      const char *const prompt
197
 
        = "Enter passphrase to unlock the disk";      
 
199
        = "Enter passphrase to unlock the disk";
198
200
      if(cryptsource == NULL){
199
201
        if(crypttarget == NULL){
200
202
          fprintf(stderr, "%s: ", prompt);
211
213
      }
212
214
    }
213
215
    ret = getline(&buffer, &n, stdin);
214
 
    if(ret > 0){
 
216
    if (ret > 0){
215
217
      status = EXIT_SUCCESS;
216
218
      /* Make n = data size instead of allocated buffer size */
217
219
      n = (size_t)ret;
232
234
      }
233
235
      break;
234
236
    }
235
 
    if(ret < 0){
236
 
      if(errno != EINTR and not feof(stdin)){
 
237
    if (ret < 0){
 
238
      if (errno != EINTR and not feof(stdin)){
237
239
        perror("getline");
238
240
        status = EXIT_FAILURE;
239
241
        break;
242
244
    /* if(ret == 0), then the only sensible thing to do is to retry to
243
245
       read from stdin */
244
246
    fputc('\n', stderr);
245
 
    if(debug and quit_now == 0){
246
 
      /* If quit_now is nonzero, we were interrupted by a signal, and
 
247
    if(debug and not quit_now){
 
248
      /* If quit_now is true, we were interrupted by a signal, and
247
249
         will print that later, so no need to show this too. */
248
250
      fprintf(stderr, "getline() returned 0, retrying.\n");
249
251
    }
250
252
  }
251
 
  
 
253
 
252
254
  free(buffer);
253
255
  
254
 
  if(debug){
 
256
  if (debug){
255
257
    fprintf(stderr, "Restoring terminal attributes\n");
256
258
  }
257
 
  if(tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_old) != 0){
 
259
  if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_old) != 0){
258
260
    perror("tcsetattr+echo");
259
261
  }
260
262
  
261
 
  if(debug){
 
263
  if (debug){
262
264
    fprintf(stderr, "%s is exiting with status %d\n", argv[0],
263
265
            status);
264
266
  }