[DRBD-cvs] r1728 - in trunk: drbd drbd/linux scripts
svn at svn.drbd.org
svn at svn.drbd.org
Thu Jan 20 14:26:07 CET 2005
Author: phil
Date: 2005-01-20 14:26:04 +0100 (Thu, 20 Jan 2005)
New Revision: 1728
Modified:
trunk/drbd/drbd_fs.c
trunk/drbd/drbd_int.h
trunk/drbd/drbd_main.c
trunk/drbd/drbd_receiver.c
trunk/drbd/linux/drbd.h
trunk/scripts/outdate-peer.sh
Log:
Kernel part of challenge/response authentication.
[ completely untested... ]
Modified: trunk/drbd/drbd_fs.c
===================================================================
--- trunk/drbd/drbd_fs.c 2005-01-19 21:24:55 UTC (rev 1727)
+++ trunk/drbd/drbd_fs.c 2005-01-20 13:26:04 UTC (rev 1728)
@@ -518,6 +518,7 @@
int i,minor;
enum ret_codes retcode;
struct net_config new_conf;
+ struct crypto_tfm* tfm = NULL;
minor=(int)(mdev-drbd_conf);
@@ -548,6 +549,20 @@
#undef O_ADDR
#undef O_PORT
+ if( new_conf.cram_hmac_alg[0] != 0) {
+ tfm = crypto_alloc_tfm(new_conf.cram_hmac_alg, 0);
+ if (tfm == NULL) {
+ retcode=CRAMAlgNotAvail;
+ goto fail_ioctl;
+ }
+ }
+
+ if ( mdev->cram_hmac_tfm ) {
+ crypto_free_tfm(mdev->cram_hmac_tfm);
+ }
+
+ mdev->cram_hmac_tfm = tfm;
+
/* IMPROVE:
We should warn the user if the LL_DEV is
used already. E.g. some FS mounted on it.
@@ -1076,6 +1091,11 @@
}
/* r == 1 which means that we changed the state... */
+ if ( mdev->cram_hmac_tfm ) {
+ crypto_free_tfm(mdev->cram_hmac_tfm);
+ mdev->cram_hmac_tfm = NULL;
+ }
+
drbd_sync_me(mdev); /* FIXME what if fsync returns error */
drbd_thread_stop(&mdev->receiver);
Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h 2005-01-19 21:24:55 UTC (rev 1727)
+++ trunk/drbd/drbd_int.h 2005-01-20 13:26:04 UTC (rev 1728)
@@ -33,7 +33,7 @@
#include <linux/sched.h>
#include <linux/bitops.h>
#include <linux/slab.h>
-
+#include <linux/crypto.h>
#include "lru_cache.h"
// module parameter, defined in drbd_main.c
@@ -295,6 +295,8 @@
ReportGenCnt,
ReportSizes,
ReportState,
+ AuthChallenge,
+ AuthResponse,
Ping, // These are sent on the meta socket...
PingAck,
@@ -333,6 +335,8 @@
[ReportGenCnt] = "ReportGenCnt",
[ReportSizes] = "ReportSizes",
[ReportState] = "ReportState",
+ [AuthChallenge] = "AuthChallenge",
+ [AuthResponse] = "AuthResponse",
[Ping] = "Ping",
[PingAck] = "PingAck",
[RecvAck] = "RecvAck",
@@ -742,6 +746,7 @@
unsigned int al_tr_number;
int al_tr_cycle;
int al_tr_pos; // position of the next transaction in the journal
+ struct crypto_tfm* cram_hmac_tfm;
};
@@ -779,6 +784,8 @@
size_t size, unsigned msg_flags);
extern int drbd_send_cmd(drbd_dev *mdev, struct socket *sock,
Drbd_Packet_Cmd cmd, Drbd_Header *h, size_t size);
+extern int drbd_send_cmd2(drbd_dev *mdev, Drbd_Packet_Cmd cmd,
+ char* data, size_t size);
extern int drbd_send_sync_param(drbd_dev *mdev, struct syncer_config *sc);
extern int drbd_send_b_ack(drbd_dev *mdev, u32 barrier_nr,
u32 set_size);
Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c 2005-01-19 21:24:55 UTC (rev 1727)
+++ trunk/drbd/drbd_main.c 2005-01-20 13:26:04 UTC (rev 1728)
@@ -807,6 +807,33 @@
return ok;
}
+int drbd_send_cmd2(drbd_dev *mdev, Drbd_Packet_Cmd cmd, char* data,
+ size_t size)
+{
+ sigset_t old_blocked;
+ Drbd_Header h;
+ int ok;
+
+ down(&mdev->data.mutex);
+ spin_lock(&mdev->send_task_lock);
+ mdev->send_task=current;
+ spin_unlock(&mdev->send_task_lock);
+
+ old_blocked = drbd_block_all_signals();
+
+ ok = _drbd_send_cmd(mdev,mdev->data.socket,cmd,&h,size,0);
+ ok = ok && ( size == drbd_send(mdev,mdev->data.socket,data,size,0) );
+
+ restore_old_sigset(old_blocked);
+
+ spin_lock(&mdev->send_task_lock);
+ mdev->send_task=NULL;
+ spin_unlock(&mdev->send_task_lock);
+ up(&mdev->data.mutex);
+
+ return ok;
+}
+
int drbd_send_sync_param(drbd_dev *mdev, struct syncer_config *sc)
{
Drbd_SyncParam_Packet p;
@@ -2031,6 +2058,10 @@
void drbd_free_resources(drbd_dev *mdev)
{
+ if ( mdev->cram_hmac_tfm ) {
+ crypto_free_tfm(mdev->cram_hmac_tfm);
+ mdev->cram_hmac_tfm = NULL;
+ }
drbd_free_sock(mdev);
drbd_free_ll_dev(mdev);
}
Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c 2005-01-19 21:24:55 UTC (rev 1727)
+++ trunk/drbd/drbd_receiver.c 2005-01-20 13:26:04 UTC (rev 1728)
@@ -47,6 +47,7 @@
#define __KERNEL_SYSCALLS__
#include <linux/unistd.h>
#include <linux/vmalloc.h>
+#include <linux/random.h>
#include <linux/drbd.h>
#include "drbd_int.h"
@@ -616,6 +617,7 @@
}
STATIC int drbd_do_handshake(drbd_dev *mdev);
+STATIC int drbd_do_auth(drbd_dev *mdev);
int drbd_connect(drbd_dev *mdev)
{
@@ -697,6 +699,13 @@
return 0;
}
+ if ( mdev->cram_hmac_tfm ) {
+ if (!drbd_do_auth(mdev)) {
+ ERR("Authentication of Peer failed.");
+ return 0;
+ }
+ }
+
clear_bit(ON_PRI_INC_HUMAN,&mdev->flags);
clear_bit(ON_PRI_INC_TIMEOUTEX,&mdev->flags);
@@ -1861,6 +1870,119 @@
return 1;
}
+#ifndef CONFIG_CRYPTO_HMAC
+STATIC int drbd_do_auth(drbd_dev *mdev)
+{
+ ERR( "This kernel was build without CONFIG_CRYPTO_HMAC.\n");
+ ERR( "You need to disable 'cram-hmac-alg' in drbd.conf.\n");
+ return 0;
+}
+#else
+#define CHALLENGE_LEN 64
+STATIC int drbd_do_auth(drbd_dev *mdev)
+{
+ char my_challenge[CHALLENGE_LEN]; /* 64 Bytes... */
+ struct scatterlist sg;
+ char *response;
+ char *right_response;
+ char *peers_ch;
+ Drbd_Header p;
+ unsigned int key_len = SHARED_SECRET_MAX;
+ unsigned int resp_size;
+ int rv;
+
+ get_random_bytes(my_challenge, CHALLENGE_LEN);
+
+ rv = drbd_send_cmd2(mdev,AuthChallenge,my_challenge,CHALLENGE_LEN);
+ if (!rv) return 0;
+
+ rv = drbd_recv_header(mdev,&p);
+ if (!rv) return 0;
+
+ if (p.command != AuthChallenge) {
+ ERR( "expected AuthChallenge packet, received: %s (0x%04x)\n",
+ cmdname(p.command), p.command );
+ return 0;
+ }
+
+ if (p.length > CHALLENGE_LEN*2 ) {
+ ERR( "expected AuthChallenge payload too big.\n");
+ return 0;
+ }
+
+ peers_ch = kmalloc(p.length,GFP_KERNEL);
+ if(peers_ch == NULL) {
+ ERR("kmalloc of peers_ch failed\n");
+ return 0;
+ }
+
+ rv = drbd_recv(mdev, peers_ch, p.length);
+
+ if (rv != p.length) {
+ ERR("short read AuthChallenge: l=%u\n", rv);
+ return 0;
+ }
+
+ resp_size = crypto_tfm_alg_digestsize(mdev->cram_hmac_tfm);
+ response = kmalloc(resp_size,GFP_KERNEL);
+ if(response == NULL) {
+ ERR("kmalloc of response failed\n");
+ return 0;
+ }
+
+ sg.page = virt_to_page(peers_ch);
+ sg.offset = offset_in_page(peers_ch);
+ sg.length = p.length;
+ crypto_hmac(mdev->cram_hmac_tfm, (u8*)mdev->conf.shared_secret,
+ &key_len, &sg, 1, response);
+
+ kfree(peers_ch);
+
+ rv = drbd_send_cmd2(mdev,AuthResponse,response,resp_size);
+ if (!rv) return 0;
+
+ rv = drbd_recv_header(mdev,&p);
+ if (!rv) return 0;
+
+ if (p.command != AuthResponse) {
+ ERR( "expected AuthResponse packet, received: %s (0x%04x)\n",
+ cmdname(p.command), p.command );
+ return 0;
+ }
+
+ if (p.length != resp_size ) {
+ ERR( "expected AuthResponse payload of wrong size.\n" );
+ return 0;
+ }
+
+ rv = drbd_recv(mdev, response , resp_size);
+
+ if (rv != resp_size) {
+ ERR("short read receiving AuthResponse: l=%u\n", rv);
+ return 0;
+ }
+
+ right_response = kmalloc(resp_size,GFP_KERNEL);
+ if(response == NULL) {
+ ERR("kmalloc of right_response failed\n");
+ return 0;
+ }
+
+ sg.page = virt_to_page(my_challenge);
+ sg.offset = offset_in_page(my_challenge);
+ sg.length = CHALLENGE_LEN;
+ crypto_hmac(mdev->cram_hmac_tfm, (u8*)mdev->conf.shared_secret,
+ &key_len, &sg, 1, right_response);
+
+ rv = ! memcmp(response,right_response,resp_size);
+
+ kfree(response);
+ kfree(right_response);
+
+ return rv;
+}
+#endif
+
int drbdd_init(struct Drbd_thread *thi)
{
drbd_dev *mdev = thi->mdev;
Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h 2005-01-19 21:24:55 UTC (rev 1727)
+++ trunk/drbd/linux/drbd.h 2005-01-20 13:26:04 UTC (rev 1728)
@@ -134,6 +134,7 @@
LDDeviceTooLarge,
MDIOError,
MDInvalid,
+ CRAMAlgNotAvail,
};
struct ioctl_disk_config {
Modified: trunk/scripts/outdate-peer.sh
===================================================================
--- trunk/scripts/outdate-peer.sh 2005-01-19 21:24:55 UTC (rev 1727)
+++ trunk/scripts/outdate-peer.sh 2005-01-20 13:26:04 UTC (rev 1728)
@@ -30,7 +30,7 @@
# time it asks you if it should ad the fingerprint to the list
# of known hosts: Say yes here.
#
-# 4. To this a second time for each IP address, now it should not ask
+# 4. Do this a second time for each IP address, now it should not ask
# any questions...
#
# Repeate this 4 steps for the other direction, BTW, you can not
More information about the drbd-cvs
mailing list