/mandos/trunk

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

« back to all changes in this revision

Viewing changes to plugins.d/passprompt.c

  • Committer: Björn Påhlsson
  • Date: 2008-07-20 02:52:20 UTC
  • Revision ID: belorn@braxen-20080720025220-r5u0388uy9iu23h6
Added following support:
Pluginbased client handler
rewritten Mandos client
       Avahi instead of udp server discovery
       openpgp encrypted key support
Passprompt stand alone application for direct console input
Added logging for Mandos server

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  -*- coding: utf-8 -*- */
2
 
/*
3
 
 * Passprompt - Read a password from the terminal and print it
4
 
 *
5
 
 * Copyright © 2007-2008 Teddy Hogeborn & Björn Påhlsson
6
 
 * 
7
 
 * This program is free software: you can redistribute it and/or
8
 
 * modify it under the terms of the GNU General Public License as
9
 
 * published by the Free Software Foundation, either version 3 of the
10
 
 * License, or (at your option) any later version.
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
 
 * General Public License for more details.
16
 
 * 
17
 
 * You should have received a copy of the GNU General Public License
18
 
 * along with this program.  If not, see
19
 
 * <http://www.gnu.org/licenses/>.
20
 
 * 
21
 
 * Contact the authors at <https://www.fukt.bsnet.se/~belorn/> and
22
 
 * <https://www.fukt.bsnet.se/~teddy/>.
23
 
 */
24
 
 
25
1
#define _GNU_SOURCE             /* getline() */
26
 
 
 
2
#define _FORTIFY_SOURCE 2
27
3
#include <termios.h>            /* struct termios, tcsetattr(),
28
4
                                   TCSAFLUSH, tcgetattr(), ECHO */
29
5
#include <unistd.h>             /* struct termios, tcsetattr(),
35
11
                                   SIGQUIT, SIGHUP, SIGTERM */
36
12
#include <stddef.h>             /* NULL, size_t */
37
13
#include <sys/types.h>          /* ssize_t */
38
 
#include <stdlib.h>             /* EXIT_SUCCESS, EXIT_FAILURE,
39
 
                                   getopt_long */
 
14
#include <stdlib.h>             /* EXIT_SUCCESS, EXIT_FAILURE */
40
15
#include <stdio.h>              /* fprintf(), stderr, getline(),
41
16
                                   stdin, feof(), perror(), fputc(),
42
 
                                   stdout, getopt_long */
 
17
                                   stdout */
43
18
#include <errno.h>              /* errno, EINVAL */
44
19
#include <iso646.h>             /* or, not */
45
20
#include <stdbool.h>            /* bool, false, true */
46
 
#include <string.h>             /* strlen, rindex, strncmp, strcmp */
47
 
#include <argp.h>               /* struct argp_option,
48
 
                                   struct argp_state, struct argp,
49
 
                                   argp_parse() */
50
21
 
51
22
volatile bool quit_now = false;
52
 
bool debug = false;
53
 
const char *argp_program_version = "passprompt 0.9";
54
 
const char *argp_program_bug_address = "<mandos@fukt.bsnet.se>";
55
23
 
56
 
static void termination_handler(__attribute__((unused))int signum){
 
24
void termination_handler(int signum){
57
25
  quit_now = true;
58
26
}
59
27
 
60
28
int main(int argc, char **argv){
61
 
  ssize_t ret;
 
29
  ssize_t ret = -1;
62
30
  size_t n;
63
31
  struct termios t_new, t_old;
64
32
  char *buffer = NULL;
65
 
  char *prefix = NULL;
66
33
  int status = EXIT_SUCCESS;
67
34
  struct sigaction old_action,
68
35
    new_action = { .sa_handler = termination_handler,
69
36
                   .sa_flags = 0 };
70
 
  {
71
 
    struct argp_option options[] = {
72
 
      { .name = "prefix", .key = 'p',
73
 
        .arg = "PREFIX", .flags = 0,
74
 
        .doc = "Prefix used before the passprompt", .group = 2 },
75
 
      { .name = "debug", .key = 128,
76
 
        .doc = "Debug mode", .group = 3 },
77
 
      { .name = NULL }
78
 
    };
79
 
  
80
 
    error_t parse_opt (int key, char *arg, struct argp_state *state) {
81
 
      /* Get the INPUT argument from `argp_parse', which we know is a
82
 
         pointer to our plugin list pointer. */
83
 
      switch (key) {
84
 
      case 'p':
85
 
        prefix = arg;
86
 
        break;
87
 
      case 128:
88
 
        debug = true;
89
 
        break;
90
 
      case ARGP_KEY_ARG:
91
 
        argp_usage (state);
92
 
        break;
93
 
      case ARGP_KEY_END:
94
 
        break;
95
 
      default:
96
 
        return ARGP_ERR_UNKNOWN;
97
 
      }
98
 
      return 0;
99
 
    }
100
 
  
101
 
    struct argp argp = { .options = options, .parser = parse_opt,
102
 
                         .args_doc = "",
103
 
                         .doc = "Mandos Passprompt -- Provides a passprompt" };
104
 
    argp_parse (&argp, argc, argv, 0, 0, NULL);
105
 
  }
106
 
    
107
 
  if (debug){
108
 
    fprintf(stderr, "Starting %s\n", argv[0]);
109
 
  }
110
 
  if (debug){
111
 
    fprintf(stderr, "Storing current terminal attributes\n");
112
 
  }
113
37
  
114
38
  if (tcgetattr(STDIN_FILENO, &t_old) != 0){
115
39
    return EXIT_FAILURE;
117
41
  
118
42
  sigemptyset(&new_action.sa_mask);
119
43
  sigaddset(&new_action.sa_mask, SIGINT);
 
44
  sigaddset(&new_action.sa_mask, SIGQUIT);
120
45
  sigaddset(&new_action.sa_mask, SIGHUP);
121
46
  sigaddset(&new_action.sa_mask, SIGTERM);
122
47
  sigaction(SIGINT, NULL, &old_action);
123
48
  if (old_action.sa_handler != SIG_IGN)
124
49
    sigaction(SIGINT, &new_action, NULL);
 
50
  sigaction(SIGQUIT, NULL, &old_action);
 
51
  if (old_action.sa_handler != SIG_IGN)
 
52
    sigaction(SIGQUIT, &new_action, NULL);
125
53
  sigaction(SIGHUP, NULL, &old_action);
126
54
  if (old_action.sa_handler != SIG_IGN)
127
55
    sigaction(SIGHUP, &new_action, NULL);
128
56
  sigaction(SIGTERM, NULL, &old_action);
129
57
  if (old_action.sa_handler != SIG_IGN)
130
58
    sigaction(SIGTERM, &new_action, NULL);
131
 
 
132
 
  
133
 
  if (debug){
134
 
    fprintf(stderr, "Removing echo flag from terminal attributes\n");
135
 
  }
136
59
  
137
60
  t_new = t_old;
138
61
  t_new.c_lflag &= ~ECHO;
140
63
    perror("tcsetattr-echo");
141
64
    return EXIT_FAILURE;
142
65
  }
143
 
 
144
 
  if (debug){
145
 
    fprintf(stderr, "Waiting for input from stdin \n");
146
 
  }
 
66
  
147
67
  while(true){
148
68
    if (quit_now){
149
69
      status = EXIT_FAILURE;
150
70
      break;
151
71
    }
152
 
 
153
 
    if(prefix){
154
 
      fprintf(stderr, "%s Password: ", prefix);
155
 
    } else {
156
 
      fprintf(stderr, "Password: ");
157
 
    }      
 
72
    fprintf(stderr, "Password: ");
158
73
    ret = getline(&buffer, &n, stdin);
159
74
    if (ret > 0){
160
75
      fprintf(stdout, "%s", buffer);
161
76
      status = EXIT_SUCCESS;
162
77
      break;
163
78
    }
 
79
    // ret == 0 makes no other sence than to retry to read from stdin
164
80
    if (ret < 0){
165
81
      if (errno != EINTR and not feof(stdin)){
166
82
        perror("getline");
168
84
        break;
169
85
      }
170
86
    }
171
 
    /* if(ret == 0), then the only sensible thing to do is to retry to
172
 
       read from stdin */
173
87
    fputc('\n', stderr);
174
88
  }
175
 
  
176
 
  if (debug){
177
 
    fprintf(stderr, "Restoring terminal attributes\n");
178
 
  }
 
89
 
179
90
  if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_old) != 0){
180
91
    perror("tcsetattr+echo");
181
92
  }
182
93
  
183
 
  if (debug){
184
 
    fprintf(stderr, "%s is exiting\n", argv[0]);
185
 
  }
186
 
  
187
94
  return status;
188
95
}