summaryrefslogtreecommitdiff
path: root/src/plugins/lan/auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/lan/auth.c')
-rw-r--r--src/plugins/lan/auth.c220
1 files changed, 220 insertions, 0 deletions
diff --git a/src/plugins/lan/auth.c b/src/plugins/lan/auth.c
new file mode 100644
index 0000000..7410e3c
--- /dev/null
+++ b/src/plugins/lan/auth.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
+ * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
+ * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
+ * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
+ * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
+ * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
+ * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <ipmitool/helper.h>
+#include <ipmitool/bswap.h>
+#include <ipmitool/ipmi.h>
+#include <ipmitool/ipmi_intf.h>
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_CRYPTO_MD2
+# include <openssl/md2.h>
+#endif
+
+#ifdef HAVE_CRYPTO_MD5
+# include <openssl/md5.h>
+#else
+# include "md5.h"
+#endif
+
+/*
+ * multi-session authcode generation for MD5
+ * H(password + session_id + msg + session_seq + password)
+ *
+ * Use OpenSSL implementation of MD5 algorithm if found
+ */
+uint8_t * ipmi_auth_md5(struct ipmi_session * s, uint8_t * data, int data_len)
+{
+#ifdef HAVE_CRYPTO_MD5
+ MD5_CTX ctx;
+ static uint8_t md[16];
+ uint32_t temp;
+
+#if WORDS_BIGENDIAN
+ temp = BSWAP_32(s->in_seq);
+#else
+ temp = s->in_seq;
+#endif
+ memset(md, 0, 16);
+ memset(&ctx, 0, sizeof(MD5_CTX));
+
+ MD5_Init(&ctx);
+ MD5_Update(&ctx, (const uint8_t *)s->authcode, 16);
+ MD5_Update(&ctx, (const uint8_t *)&s->session_id, 4);
+ MD5_Update(&ctx, (const uint8_t *)data, data_len);
+ MD5_Update(&ctx, (const uint8_t *)&temp, sizeof(uint32_t));
+ MD5_Update(&ctx, (const uint8_t *)s->authcode, 16);
+ MD5_Final(md, &ctx);
+
+ if (verbose > 3)
+ printf(" MD5 AuthCode : %s\n", buf2str(md, 16));
+
+ return md;
+#else /*HAVE_CRYPTO_MD5*/
+ md5_state_t state;
+ static md5_byte_t digest[16];
+ uint32_t temp;
+
+ memset(digest, 0, 16);
+ memset(&state, 0, sizeof(md5_state_t));
+
+ md5_init(&state);
+
+ md5_append(&state, (const md5_byte_t *)s->authcode, 16);
+ md5_append(&state, (const md5_byte_t *)&s->session_id, 4);
+ md5_append(&state, (const md5_byte_t *)data, data_len);
+
+#if WORDS_BIGENDIAN
+ temp = BSWAP_32(s->in_seq);
+#else
+ temp = s->in_seq;
+#endif
+ md5_append(&state, (const md5_byte_t *)&temp, 4);
+ md5_append(&state, (const md5_byte_t *)s->authcode, 16);
+
+ md5_finish(&state, digest);
+
+ if (verbose > 3)
+ printf(" MD5 AuthCode : %s\n", buf2str(digest, 16));
+ return digest;
+#endif /*HAVE_CRYPTO_MD5*/
+}
+
+/*
+ * multi-session authcode generation for MD2
+ * H(password + session_id + msg + session_seq + password)
+ *
+ * Use OpenSSL implementation of MD2 algorithm if found.
+ * This function is analogous to ipmi_auth_md5
+ */
+uint8_t * ipmi_auth_md2(struct ipmi_session * s, uint8_t * data, int data_len)
+{
+#ifdef HAVE_CRYPTO_MD2
+ MD2_CTX ctx;
+ static uint8_t md[16];
+ uint32_t temp;
+
+#if WORDS_BIGENDIAN
+ temp = BSWAP_32(s->in_seq);
+#else
+ temp = s->in_seq;
+#endif
+ memset(md, 0, 16);
+ memset(&ctx, 0, sizeof(MD2_CTX));
+
+ MD2_Init(&ctx);
+ MD2_Update(&ctx, (const uint8_t *)s->authcode, 16);
+ MD2_Update(&ctx, (const uint8_t *)&s->session_id, 4);
+ MD2_Update(&ctx, (const uint8_t *)data, data_len);
+ MD2_Update(&ctx, (const uint8_t *)&temp, sizeof(uint32_t));
+ MD2_Update(&ctx, (const uint8_t *)s->authcode, 16);
+ MD2_Final(md, &ctx);
+
+ if (verbose > 3)
+ printf(" MD2 AuthCode : %s\n", buf2str(md, 16));
+
+ return md;
+#else /*HAVE_CRYPTO_MD2*/
+ static uint8_t md[16];
+ memset(md, 0, 16);
+ printf("WARNING: No internal support for MD2! "
+ "Please re-compile with OpenSSL.\n");
+ return md;
+#endif /*HAVE_CRYPTO_MD2*/
+}
+
+/* special authentication method */
+uint8_t * ipmi_auth_special(struct ipmi_session * s)
+{
+#ifdef HAVE_CRYPTO_MD5
+ MD5_CTX ctx;
+ static uint8_t md[16];
+ uint8_t challenge[16];
+ int i;
+
+ memset(challenge, 0, 16);
+ memset(md, 0, 16);
+ memset(&ctx, 0, sizeof(MD5_CTX));
+
+ MD5_Init(&ctx);
+ MD5_Update(&ctx, (const uint8_t *)s->authcode, strlen((const char *)s->authcode));
+ MD5_Final(md, &ctx);
+
+ for (i=0; i<16; i++)
+ challenge[i] = s->challenge[i] ^ md[i];
+
+ memset(md, 0, 16);
+ memset(&ctx, 0, sizeof(MD5_CTX));
+
+ MD5_Init(&ctx);
+ MD5_Update(&ctx, (const uint8_t *)challenge, 16);
+ MD5_Final(md, &ctx);
+
+ return md;
+#else /*HAVE_CRYPTO_MD5*/
+ int i;
+ md5_state_t state;
+ static md5_byte_t digest[16];
+ uint8_t challenge[16];
+
+ memset(challenge, 0, 16);
+ memset(digest, 0, 16);
+ memset(&state, 0, sizeof(md5_state_t));
+
+ md5_init(&state);
+ md5_append(&state, (const md5_byte_t *)s->authcode, strlen(s->authcode));
+ md5_finish(&state, digest);
+
+ for (i=0; i<16; i++)
+ challenge[i] = s->challenge[i] ^ digest[i];
+
+ memset(digest, 0, 16);
+ memset(&state, 0, sizeof(md5_state_t));
+
+ md5_init(&state);
+ md5_append(&state, (const md5_byte_t *)challenge, 16);
+ md5_finish(&state, digest);
+
+ return digest;
+#endif /*HAVE_CRYPTO_MD5*/
+}
+