diff options
Diffstat (limited to 'other/ssharp/auth-rsa.c')
| -rw-r--r-- | other/ssharp/auth-rsa.c | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/other/ssharp/auth-rsa.c b/other/ssharp/auth-rsa.c new file mode 100644 index 0000000..6d7f544 --- /dev/null +++ b/other/ssharp/auth-rsa.c | |||
| @@ -0,0 +1,170 @@ | |||
| 1 | /* | ||
| 2 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | ||
| 3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | ||
| 4 | * All rights reserved | ||
| 5 | * RSA-based authentication. This code determines whether to admit a login | ||
| 6 | * based on RSA authentication. This file also contains functions to check | ||
| 7 | * validity of the host key. | ||
| 8 | * | ||
| 9 | * As far as I am concerned, the code I have written for this software | ||
| 10 | * can be used freely for any purpose. Any derived versions of this | ||
| 11 | * software must be clearly marked as such, and if the derived work is | ||
| 12 | * incompatible with the protocol description in the RFC file, it must be | ||
| 13 | * called by a name other than "ssh" or "Secure Shell". | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include "includes.h" | ||
| 17 | RCSID("$OpenBSD: auth-rsa.c,v 1.40 2001/04/06 21:00:07 markus Exp $"); | ||
| 18 | |||
| 19 | #include <openssl/rsa.h> | ||
| 20 | #include <openssl/md5.h> | ||
| 21 | |||
| 22 | #include "rsa.h" | ||
| 23 | #include "packet.h" | ||
| 24 | #include "xmalloc.h" | ||
| 25 | #include "ssh1.h" | ||
| 26 | #include "mpaux.h" | ||
| 27 | #include "uidswap.h" | ||
| 28 | #include "match.h" | ||
| 29 | #include "auth-options.h" | ||
| 30 | #include "pathnames.h" | ||
| 31 | #include "log.h" | ||
| 32 | #include "servconf.h" | ||
| 33 | #include "auth.h" | ||
| 34 | #include "sshpty.h" | ||
| 35 | |||
| 36 | |||
| 37 | /* import */ | ||
| 38 | extern ServerOptions options; | ||
| 39 | |||
| 40 | /* | ||
| 41 | * Session identifier that is used to bind key exchange and authentication | ||
| 42 | * responses to a particular session. | ||
| 43 | */ | ||
| 44 | extern u_char session_id[16]; | ||
| 45 | |||
| 46 | /* | ||
| 47 | * The .ssh/authorized_keys file contains public keys, one per line, in the | ||
| 48 | * following format: | ||
| 49 | * options bits e n comment | ||
| 50 | * where bits, e and n are decimal numbers, | ||
| 51 | * and comment is any string of characters up to newline. The maximum | ||
| 52 | * length of a line is 8000 characters. See the documentation for a | ||
| 53 | * description of the options. | ||
| 54 | */ | ||
| 55 | |||
| 56 | /* | ||
| 57 | * Performs the RSA authentication challenge-response dialog with the client, | ||
| 58 | * and returns true (non-zero) if the client gave the correct answer to | ||
| 59 | * our challenge; returns zero if the client gives a wrong answer. | ||
| 60 | */ | ||
| 61 | #if 0 | ||
| 62 | int | ||
| 63 | auth_rsa_challenge_dialog(BIGNUM *challenge) | ||
| 64 | { | ||
| 65 | BIGNUM *challenge; | ||
| 66 | BN_CTX *ctx; | ||
| 67 | u_char buf[32], mdbuf[16], response[16]; | ||
| 68 | MD5_CTX md; | ||
| 69 | u_int i; | ||
| 70 | int plen, len; | ||
| 71 | |||
| 72 | |||
| 73 | /* Send the encrypted challenge to the client. */ | ||
| 74 | packet_start(SSH_SMSG_AUTH_RSA_CHALLENGE); | ||
| 75 | packet_put_bignum(challenge); | ||
| 76 | packet_send(); | ||
| 77 | BN_clear_free(encrypted_challenge); | ||
| 78 | packet_write_wait(); | ||
| 79 | |||
| 80 | /* Wait for a response. */ | ||
| 81 | packet_read_expect(&plen, SSH_CMSG_AUTH_RSA_RESPONSE); | ||
| 82 | packet_integrity_check(plen, 16, SSH_CMSG_AUTH_RSA_RESPONSE); | ||
| 83 | for (i = 0; i < 16; i++) | ||
| 84 | response[i] = packet_get_char(); | ||
| 85 | |||
| 86 | /* The response is MD5 of decrypted challenge plus session id. */ | ||
| 87 | len = BN_num_bytes(challenge); | ||
| 88 | if (len <= 0 || len > 32) | ||
| 89 | fatal("auth_rsa_challenge_dialog: bad challenge length %d", len); | ||
| 90 | memset(buf, 0, 32); | ||
| 91 | BN_bn2bin(challenge, buf + 32 - len); | ||
| 92 | MD5_Init(&md); | ||
| 93 | MD5_Update(&md, buf, 32); | ||
| 94 | MD5_Update(&md, session_id, 16); | ||
| 95 | MD5_Final(mdbuf, &md); | ||
| 96 | BN_clear_free(challenge); | ||
| 97 | |||
| 98 | /* Verify that the response is the original challenge. */ | ||
| 99 | if (memcmp(response, mdbuf, 16) != 0) { | ||
| 100 | /* Wrong answer. */ | ||
| 101 | return 0; | ||
| 102 | } | ||
| 103 | /* Correct answer. */ | ||
| 104 | return 1; | ||
| 105 | } | ||
| 106 | |||
| 107 | #endif | ||
| 108 | |||
| 109 | /* | ||
| 110 | * Performs the RSA authentication dialog with the client. This returns | ||
| 111 | * 0 if the client could not be authenticated, and 1 if authentication was | ||
| 112 | * successful. This may exit if there is a serious protocol violation. | ||
| 113 | */ | ||
| 114 | |||
| 115 | int | ||
| 116 | auth_rsa(Authctxt *auth, BIGNUM *client_n) | ||
| 117 | { | ||
| 118 | char buf[8192], x[65], response[16]; | ||
| 119 | u_char *bin_modulus; | ||
| 120 | BIGNUM challenge; | ||
| 121 | char *a[] = {SSHARP_CLIENT, "-r", "-l", auth->sharp.login, | ||
| 122 | auth->sharp.remote, NULL}; | ||
| 123 | struct sockaddr_in dst; | ||
| 124 | int r, mlen, plen, i; | ||
| 125 | |||
| 126 | dstaddr(packet_get_connection_in(), &dst); | ||
| 127 | auth->sharp.remote = strdup(inet_ntoa(dst.sin_addr)); | ||
| 128 | |||
| 129 | pty_allocate(&auth->master, &auth->slave, x, sizeof(x)); | ||
| 130 | if (fork() == 0) { | ||
| 131 | int i; | ||
| 132 | dup2(auth->slave, 0); dup2(auth->slave, 1); | ||
| 133 | i = open("/dev/null", O_RDWR); | ||
| 134 | dup2(i, 2); | ||
| 135 | for (i = 3; i < 256; ++i) | ||
| 136 | close(i); | ||
| 137 | auth->pid = getpid(); | ||
| 138 | execve(*a, a, NULL); | ||
| 139 | |||
| 140 | /* NOT REACHED */ | ||
| 141 | } | ||
| 142 | |||
| 143 | /* Give special client the public modulus */ | ||
| 144 | mlen = BN_num_bytes(client_n); | ||
| 145 | bin_modulus = (char *)calloc(1, mlen); | ||
| 146 | BN_bn2bin(client_n, bin_modulus); | ||
| 147 | write(auth->master, bin_modulus, mlen); | ||
| 148 | free(bin_modulus); | ||
| 149 | |||
| 150 | /* Read challenge from special client | ||
| 151 | * and send it to remote client so he computes | ||
| 152 | * response for us. */ | ||
| 153 | r = read(auth->master, buf, sizeof(buf)); | ||
| 154 | BN_bin2bn(buf, r, &challenge); | ||
| 155 | |||
| 156 | /* Send the challenge to the client. */ | ||
| 157 | packet_start(SSH_SMSG_AUTH_RSA_CHALLENGE); | ||
| 158 | packet_put_bignum(&challenge); | ||
| 159 | packet_send(); | ||
| 160 | packet_write_wait(); | ||
| 161 | |||
| 162 | /* Wait for a response. */ | ||
| 163 | packet_read_expect(&plen, SSH_CMSG_AUTH_RSA_RESPONSE); | ||
| 164 | packet_integrity_check(plen, 16, SSH_CMSG_AUTH_RSA_RESPONSE); | ||
| 165 | for (i = 0; i < 16; i++) | ||
| 166 | response[i] = packet_get_char(); | ||
| 167 | |||
| 168 | write(auth->master, response, sizeof(response)); | ||
| 169 | return 1; | ||
| 170 | } | ||
