aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/widget-skey.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/widget-skey.c')
-rw-r--r--src/widget-skey.c252
1 files changed, 252 insertions, 0 deletions
diff --git a/src/widget-skey.c b/src/widget-skey.c
new file mode 100644
index 0000000..9fa69ea
--- /dev/null
+++ b/src/widget-skey.c
@@ -0,0 +1,252 @@
1/*
2 * OTP Utilities
3 * Copyright (C) 2022 David M. Syzdek <david@syzdek.net>.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * * Neither the name of David M. Syzdek nor the
15 * names of its contributors may be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
19 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID M SYZDEK BE LIABLE FOR
22 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30/*
31 * @file src/widget-otp.c
32 */
33#define _SRC_WIDGET_OTP_C 1
34
35///////////////
36// //
37// Headers //
38// //
39///////////////
40#pragma mark - Headers
41
42#include <otputil_compat.h>
43
44#ifdef HAVE_CONFIG_H
45# include <config.h>
46#endif
47
48#include <errno.h>
49#include <assert.h>
50#include <stdarg.h>
51#include <string.h>
52#include <strings.h>
53#include <stdlib.h>
54#include <getopt.h>
55#include <stdio.h>
56
57#include "otputil.h"
58
59
60//////////////////
61// //
62// Prototypes //
63// //
64//////////////////
65#pragma mark - Prototypes
66
67static int
68otputil_widget_skey_verbose(
69 otputil_config_t * cnf,
70 const otputil_bv_t * otp_data,
71 const otputil_bv_t * otp_verify,
72 const char * status );
73
74
75/////////////////
76// //
77// Functions //
78// //
79/////////////////
80#pragma mark - Functions
81
82
83//---------------//
84// main function //
85//---------------//
86#pragma mark main function
87
88int
89otputil_widget_skey(
90 otputil_config_t * cnf )
91{
92 int rc;
93 int hash;
94 int seq;
95 uint64_t meth;
96 char * pass;
97 char * endptr;
98 const char * str;
99 const char * status;
100 static char buff[OTPUTIL_MAX_ENCODE_SIZE];
101 otputil_bv_t skey_data;
102 otputil_bv_t skey_verify;
103 otputil_bv_t * a;
104 otputil_bv_t * b;
105 uint8_t skey_data_val[512];
106 uint8_t skey_verify_val[512];
107
108 assert(cnf != NULL);
109
110 // set OTP method
111 meth = OTPUTIL_METH_SKEY;
112 if ((rc = otputil_set_param(NULL, OTPUTIL_OPT_METHOD, &meth)) == -1)
113 {
114 fprintf(stderr, "%s: otputil_set_param(METHOD): %s\n", cnf->prog_name, otputil_err2string(rc));
115 return(1);
116 };
117
118 // initial processing of cli arguments
119 if ((rc = otputil_arguments(cnf, cnf->argc, cnf->argv)) != 0)
120 return((rc == -1) ? 0 : 1);
121 if (cnf->argc > optind)
122 {
123 seq = (int)strtoul(cnf->argv[optind], &endptr, 0);
124 if ((endptr == cnf->argv[optind]) || (endptr[0] != '\0'))
125 {
126 fprintf(stderr, "%s: invalid sequence number\n", cnf->prog_name);
127 fprintf(stderr, "Try `%s --help' for more information.\n", cnf->prog_name);
128 return(1);
129 };
130 if ((rc = otputil_set_param(NULL, OTPUTIL_OPT_SKEY_SEQ, &seq)) != OTPUTIL_SUCCESS)
131 {
132 fprintf(stderr, "%s: otputil_set_param(SKEY_SEQ): %s\n", cnf->prog_name, otputil_err2string(rc));
133 return(1);
134 };
135 };
136
137 // verify password was provided
138 otputil_get_param(NULL, OTPUTIL_OPT_SKEY_PASS, &pass);
139 if (!(pass))
140 {
141 str = otputil_getpass("Enter user's password:", NULL, 0);
142 if ((rc = otputil_set_param(NULL, OTPUTIL_OPT_SKEY_PASS, str)) != OTPUTIL_SUCCESS)
143 {
144 fprintf(stderr, "%s: otputil_set_param(SKEY_PASS): %s\n", cnf->prog_name, otputil_err2string(rc));
145 return(1);
146 };
147 };
148 if ((pass))
149 free(pass);
150
151 // generate OTP pass phrase
152 if ((str = otputil_str(NULL, buff, sizeof(buff))) == NULL)
153 {
154 fprintf(stderr, "%s: internal error\n", cnf->prog_name);
155 return(1);
156 };
157 skey_data.bv_val = skey_data_val;
158 skey_data.bv_len = sizeof(skey_data_val);
159 otputil_get_param(NULL, OTPUTIL_OPT_OTP_HASH, &hash);
160 otputil_otp_decode(str, &skey_data, hash);
161
162 // verify existing code
163 if ((cnf->otp_pass))
164 {
165 skey_verify.bv_val = skey_verify_val;
166 skey_verify.bv_len = sizeof(skey_verify_val);
167 if (otputil_otp_decode(cnf->otp_pass, &skey_verify, hash) == NULL)
168 {
169 fprintf(stderr, "%s: not a valid OTP passphrase to verify\n", cnf->prog_name);
170 return(1);
171 };
172 a = &skey_data;
173 b = &skey_verify;
174 rc = ((otputil_bvcmp(&a, &b))) ? 2 : 0;
175 status = ((rc)) ? "invalid code" : "valid code";
176 if ((cnf->verbose))
177 otputil_widget_skey_verbose(cnf, &skey_data, &skey_verify, status);
178 else
179 printf("%s\n", status);
180 return(rc);
181 };
182
183 // print results
184 if ( ((cnf->quiet)) || (!(cnf->verbose)) )
185 {
186 printf("%s\n", str);
187 return(0);
188 };
189 otputil_widget_skey_verbose(cnf, &skey_data, NULL, NULL);
190
191 return(0);
192}
193
194
195int
196otputil_widget_skey_usage(
197 otputil_config_t * cnf )
198{
199 assert(cnf != NULL);
200 printf("ALGORITHMS:\n");
201 printf(" md4 MD4 Message-Digest Algorithm\n");
202 printf(" md5 MD5 message-digest algorithm\n");
203 printf(" sha1 SHA-1 (Secure Hash Algorithm 1)\n");
204 printf(" sha256 SHA-2 (Secure Hash Algorithm 2) with 256 bits\n");
205 printf(" sha512 SHA-2 (Secure Hash Algorithm 2) with 512 bits\n");
206 return(0);
207}
208
209
210int
211otputil_widget_skey_verbose(
212 otputil_config_t * cnf,
213 const otputil_bv_t * skey_data,
214 const otputil_bv_t * skey_verify,
215 const char * status )
216{
217 int skey_hash;
218 int skey_seq;
219 char * util_desc;
220 char * skey_pass;
221
222 otputil_get_param(NULL, OTPUTIL_OPT_SKEY_SEQ, &skey_seq);
223 otputil_get_param(NULL, OTPUTIL_OPT_SKEY_HASH, &skey_hash);
224 otputil_get_param(NULL, OTPUTIL_OPT_SKEY_PASS, &skey_pass);
225 otputil_get_param(NULL, OTPUTIL_OPT_DESC, &util_desc);
226
227 // print secret information
228 printf("S/KEY Secret:\n");
229 printf(" Description: %s\n", (((util_desc)) ? util_desc : "n/a") );
230 printf(" Method: S/KEY (RFC1760)\n");
231 printf(" Hash: %s\n", otputil_md2str(skey_hash));
232 if (cnf->verbose > 1)
233 printf(" User Passsword: %s\n", skey_pass);
234 else
235 printf(" User Passsword: ********\n");
236 printf(" Sequence: %i\n", skey_seq );
237 if ((cnf->otp_pass))
238 printf(" Entered Pass Phrase: %s\n", cnf->otp_pass );
239 if ((cnf->otp_pass))
240 printf(" Expected Code: %s\n", otputil_otp_encode(skey_verify, NULL, 0, OTPUTIL_ENC_HEX) );
241 printf(" OTP Code: %s\n", otputil_otp_encode(skey_data, NULL, 0, OTPUTIL_ENC_HEX) );
242 if ((cnf->otp_pass))
243 printf(" Expected Pass Phrase: %s\n", otputil_otp_encode(skey_verify, NULL, 0, OTPUTIL_ENC_SIXWORD) );
244 printf(" OTP Pass Phrase: %s\n", otputil_otp_encode(skey_data, NULL, 0, OTPUTIL_ENC_SIXWORD) );
245 if ((status))
246 printf(" Status: %s\n", status );
247 printf("\n");
248
249 return(0);
250}
251
252/* end of source file */