/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-01-18 21:18:26 UTC
  • mto: This revision was merged to the branch mainline in revision 6.
  • Revision ID: belorn@legolas-20080118211826-5rbwo54l4bwim5x2
Client:
        [Working version in initrd for booting]
        Added #ifdef DEBUG statements through out the program
        Added support to keep bouth tcp and udp up at the same time
        Catching several more error return codes that was unchecked.
        Starts the Network interface during startup.
        Added support for entering password on console
        Added error handling, like looping until a password has been received.
        Added cleanup handling so console state is always restored
                
removed:
        Old server.cpp [see next version]
        Test certificates

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
 
#define _GNU_SOURCE             /* getline() */
26
 
 
27
 
#include <termios.h>            /* struct termios, tcsetattr(),
28
 
                                   TCSAFLUSH, tcgetattr(), ECHO */
29
 
#include <unistd.h>             /* struct termios, tcsetattr(),
30
 
                                   STDIN_FILENO, TCSAFLUSH,
31
 
                                   tcgetattr(), ECHO */
32
 
#include <signal.h>             /* sig_atomic_t, raise(), struct
33
 
                                   sigaction, sigemptyset(),
34
 
                                   sigaction(), sigaddset(), SIGINT,
35
 
                                   SIGQUIT, SIGHUP, SIGTERM */
36
 
#include <stddef.h>             /* NULL, size_t */
37
 
#include <sys/types.h>          /* ssize_t */
38
 
#include <stdlib.h>             /* EXIT_SUCCESS, EXIT_FAILURE,
39
 
                                   getopt_long */
40
 
#include <stdio.h>              /* fprintf(), stderr, getline(),
41
 
                                   stdin, feof(), perror(), fputc(),
42
 
                                   stdout, getopt_long */
43
 
#include <errno.h>              /* errno, EINVAL */
44
 
#include <iso646.h>             /* or, not */
45
 
#include <stdbool.h>            /* bool, false, true */
46
 
#include <string.h>             /* strlen, rindex, strncmp, strcmp */
47
 
#include <getopt.h>             /* getopt_long */
48
 
 
49
 
volatile bool quit_now = false;
50
 
bool debug = false;
51
 
 
52
 
static void termination_handler(__attribute__((unused))int signum){
53
 
  quit_now = true;
54
 
}
55
 
 
56
 
int main(int argc, char **argv){
57
 
  ssize_t ret;
58
 
  size_t n;
59
 
  struct termios t_new, t_old;
60
 
  char *buffer = NULL;
61
 
  char *prefix = NULL;
62
 
  int status = EXIT_SUCCESS;
63
 
  struct sigaction old_action,
64
 
    new_action = { .sa_handler = termination_handler,
65
 
                   .sa_flags = 0 };
66
 
 
67
 
  while (true){
68
 
    static struct option long_options[] = {
69
 
      {"debug", no_argument, (int *)&debug, 1},
70
 
      {"prefix", required_argument, 0, 'p'},
71
 
      {0, 0, 0, 0} };
72
 
 
73
 
    int option_index = 0;
74
 
    ret = getopt_long (argc, argv, "p:", long_options, &option_index);
75
 
 
76
 
    if (ret == -1){
77
 
      break;
78
 
    }
79
 
      
80
 
    switch(ret){
81
 
    case 0:
82
 
      break;
83
 
    case 'p':
84
 
      prefix = optarg;
85
 
      break;
86
 
    default:
87
 
      fprintf(stderr, "bad arguments\n");
88
 
      exit(EXIT_FAILURE);
89
 
    }
90
 
  }
91
 
      
92
 
  if (debug){
93
 
    fprintf(stderr, "Starting %s\n", argv[0]);
94
 
  }
95
 
  if (debug){
96
 
    fprintf(stderr, "Storing current terminal attributes\n");
97
 
  }
98
 
  
99
 
  if (tcgetattr(STDIN_FILENO, &t_old) != 0){
100
 
    return EXIT_FAILURE;
101
 
  }
102
 
  
103
 
  sigemptyset(&new_action.sa_mask);
104
 
  sigaddset(&new_action.sa_mask, SIGINT);
105
 
  sigaddset(&new_action.sa_mask, SIGHUP);
106
 
  sigaddset(&new_action.sa_mask, SIGTERM);
107
 
  sigaction(SIGINT, NULL, &old_action);
108
 
  if (old_action.sa_handler != SIG_IGN)
109
 
    sigaction(SIGINT, &new_action, NULL);
110
 
  sigaction(SIGHUP, NULL, &old_action);
111
 
  if (old_action.sa_handler != SIG_IGN)
112
 
    sigaction(SIGHUP, &new_action, NULL);
113
 
  sigaction(SIGTERM, NULL, &old_action);
114
 
  if (old_action.sa_handler != SIG_IGN)
115
 
    sigaction(SIGTERM, &new_action, NULL);
116
 
 
117
 
  
118
 
  if (debug){
119
 
    fprintf(stderr, "Removing echo flag from terminal attributes\n");
120
 
  }
121
 
  
122
 
  t_new = t_old;
123
 
  t_new.c_lflag &= ~ECHO;
124
 
  if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_new) != 0){
125
 
    perror("tcsetattr-echo");
126
 
    return EXIT_FAILURE;
127
 
  }
128
 
 
129
 
  if (debug){
130
 
    fprintf(stderr, "Waiting for input from stdin \n");
131
 
  }
132
 
  while(true){
133
 
    if (quit_now){
134
 
      status = EXIT_FAILURE;
135
 
      break;
136
 
    }
137
 
 
138
 
    if(prefix){
139
 
      fprintf(stderr, "%s Password: ", prefix);
140
 
    } else {
141
 
      fprintf(stderr, "Password: ");
142
 
    }      
143
 
    ret = getline(&buffer, &n, stdin);
144
 
    if (ret > 0){
145
 
      fprintf(stdout, "%s", buffer);
146
 
      status = EXIT_SUCCESS;
147
 
      break;
148
 
    }
149
 
    if (ret < 0){
150
 
      if (errno != EINTR and not feof(stdin)){
151
 
        perror("getline");
152
 
        status = EXIT_FAILURE;
153
 
        break;
154
 
      }
155
 
    }
156
 
    /* if(ret == 0), then the only sensible thing to do is to retry to
157
 
       read from stdin */
158
 
    fputc('\n', stderr);
159
 
  }
160
 
  
161
 
  if (debug){
162
 
    fprintf(stderr, "Restoring terminal attributes\n");
163
 
  }
164
 
  if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_old) != 0){
165
 
    perror("tcsetattr+echo");
166
 
  }
167
 
  
168
 
  if (debug){
169
 
    fprintf(stderr, "%s is exiting\n", argv[0]);
170
 
  }
171
 
  
172
 
  return status;
173
 
}