summaryrefslogtreecommitdiff
path: root/trunk/qpid/ruby/ext/sasl/sasl.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/qpid/ruby/ext/sasl/sasl.c')
-rw-r--r--trunk/qpid/ruby/ext/sasl/sasl.c472
1 files changed, 0 insertions, 472 deletions
diff --git a/trunk/qpid/ruby/ext/sasl/sasl.c b/trunk/qpid/ruby/ext/sasl/sasl.c
deleted file mode 100644
index 2d4e40d30e..0000000000
--- a/trunk/qpid/ruby/ext/sasl/sasl.c
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
-*/
-
-#include <stdio.h>
-#include <unistd.h>
-#include <malloc.h>
-#include <string.h>
-#include <sasl/sasl.h>
-#include <ruby.h>
-
-static VALUE mSasl;
-
-#define INPUT_SIZE 512
-#define MECH_SIZE 32
-
-typedef void* sasl_context_t;
-
-#define QSASL_OK 0
-#define QSASL_CONTINUE 1
-#define QSASL_FAILED 2
-
-typedef struct {
- char magic[8];
- sasl_conn_t* conn;
- sasl_callback_t callbacks[8];
- char* userName;
- char* password;
- char* operUserName;
- unsigned int minSsf;
- unsigned int maxSsf;
- char mechanism[MECH_SIZE];
- char input[INPUT_SIZE];
-} context_t;
-
-//
-// Resolve forward references
-//
-static VALUE qsasl_free(int, VALUE*, VALUE);
-
-//
-// Validate an input string to ensure that it is either NULL or of reasonable size.
-//
-static int qsasl_valid(char* str)
-{
- int idx;
-
- if (str == 0)
- return 1;
-
- for (idx = 0; idx < INPUT_SIZE; idx++) {
- if (str[idx] == '\0')
- return 1;
- }
-
- return 0;
-}
-
-//
-// SASL callback for identity and authentication identity.
-//
-static int qsasl_cb_user(void* _context, int id, const char **result, unsigned *len)
-{
- context_t* context = (context_t*) _context;
-
- if (context->userName)
- *result = context->userName;
-
- return SASL_OK;
-}
-
-//
-// SASL callback for passwords.
-//
-static int qsasl_cb_password(sasl_conn_t* conn, void* _context, int id, sasl_secret_t **psecret)
-{
- context_t* context = (context_t*) _context;
- sasl_secret_t* secret;
- size_t length;
-
- if (context->password)
- length = strlen(context->password);
- else
- length = 0;
-
- secret = (sasl_secret_t*) malloc(sizeof(sasl_secret_t) + length);
- secret->len = length;
- if (length)
- memcpy(secret->data, context->password, length);
- *psecret = secret;
-
- return SASL_OK;
-}
-
-//
-// Interactively prompt the user for authentication data.
-//
-static void qsasl_prompt(sasl_context_t _context, sasl_interact_t* interact)
-{
- context_t* context = (context_t*) _context;
- char *pass;
- char *input;
- char passwdPrompt[100];
-
- if (interact->id == SASL_CB_PASS) {
- strncpy(passwdPrompt, interact->prompt, 95);
- strcat(passwdPrompt, ": ");
- pass = getpass(passwdPrompt);
- strncpy(context->input, pass, INPUT_SIZE - 1);
- context->input[INPUT_SIZE - 1] = '\0';
- } else {
- printf(interact->prompt);
- if (interact->defresult) {
- printf(" (%s)", interact->defresult);
- }
- printf(": ");
- input = fgets(context->input, INPUT_SIZE, stdin);
- if (input != context->input) {
- rb_raise(rb_eRuntimeError, "Unexpected EOF on interactive prompt");
- }
- }
-
- interact->result = context->input;
- interact->len = strlen(context->input);
-}
-
-//
-// Initialize the SASL client library.
-//
-static VALUE qsasl_client_init()
-{
- int result;
-
- result = sasl_client_init(0);
- if (result != SASL_OK)
- rb_raise(rb_eRuntimeError,
- "sasl_client_init failed: %d - %s",
- result, sasl_errstring(result, -0, 0));
- return Qnil;
-}
-
-//
-// Allocate a new SASL client context.
-//
-static VALUE qsasl_client_new(int argc, VALUE *argv, VALUE obj)
-{
- char* mechanism = 0;
- char* serviceName = 0;
- char* hostName = 0;
- char* userName = 0;
- char* password = 0;
- unsigned int minSsf = 0;
- unsigned int maxSsf = 65535;
-
- int result;
- int i = 0;
- context_t *context;
- sasl_security_properties_t secprops;
-
- if (argc != 7)
- rb_raise(rb_eRuntimeError, "Wrong number of arguments");
-
- if (!NIL_P(argv[0]))
- mechanism = StringValuePtr(argv[0]);
- if (!NIL_P(argv[1]))
- serviceName = StringValuePtr(argv[1]);
- if (!NIL_P(argv[2]))
- hostName = StringValuePtr(argv[2]);
- if (!NIL_P(argv[3]))
- userName = StringValuePtr(argv[3]);
- if (!NIL_P(argv[4]))
- password = StringValuePtr(argv[4]);
- minSsf = FIX2INT(argv[5]);
- maxSsf = FIX2INT(argv[6]);
-
- if (!qsasl_valid(mechanism) || !qsasl_valid(serviceName) ||
- !qsasl_valid(hostName) || !qsasl_valid(userName) ||
- !qsasl_valid(password)) {
- rb_raise(rb_eRuntimeError, "Invalid string argument");
- }
-
- context = (context_t*) malloc(sizeof(context_t));
- memset(context, 0, sizeof(context_t));
- strcpy(context->magic, "QSASL01");
-
- context->minSsf = minSsf;
- context->maxSsf = maxSsf;
- if (mechanism != 0) {
- strncpy(context->mechanism, mechanism, MECH_SIZE - 1);
- context->mechanism[MECH_SIZE - 1] = '\0';
- }
-
- context->callbacks[i].id = SASL_CB_GETREALM;
- context->callbacks[i].proc = 0;
- context->callbacks[i++].context = 0;
-
- if (userName != 0 && userName[0] != '\0') {
- context->userName = (char*) malloc(strlen(userName) + 1);
- strcpy(context->userName, userName);
-
- context->callbacks[i].id = SASL_CB_USER;
- context->callbacks[i].proc = qsasl_cb_user;
- context->callbacks[i++].context = context;
-
- context->callbacks[i].id = SASL_CB_AUTHNAME;
- context->callbacks[i].proc = qsasl_cb_user;
- context->callbacks[i++].context = context;
- }
-
- context->callbacks[i].id = SASL_CB_PASS;
- if (password != 0 && password[0] != '\0') {
- context->password = (char*) malloc(strlen(password) + 1);
- strcpy(context->password, password);
-
- context->callbacks[i].proc = qsasl_cb_password;
- } else
- context->callbacks[i].proc = 0;
- context->callbacks[i++].context = context;
-
- context->callbacks[i].id = SASL_CB_LIST_END;
- context->callbacks[i].proc = 0;
- context->callbacks[i++].context = 0;
-
- result = sasl_client_new(serviceName, hostName, 0, 0,
- context->callbacks, 0, &context->conn);
-
- if (result != SASL_OK) {
- context->conn = 0;
- qsasl_free(1, (VALUE*) &context, Qnil);
- rb_raise(rb_eRuntimeError, "sasl_client_new failed: %d - %s",
- result, sasl_errstring(result, 0, 0));
- }
-
- secprops.min_ssf = minSsf;
- secprops.max_ssf = maxSsf;
- secprops.maxbufsize = 65535;
- secprops.property_names = 0;
- secprops.property_values = 0;
- secprops.security_flags = 0;//TODO: provide means for application to configure these
-
- result = sasl_setprop(context->conn, SASL_SEC_PROPS, &secprops);
- if (result != SASL_OK) {
- qsasl_free(1, (VALUE*) &context, Qnil);
- rb_raise(rb_eRuntimeError, "sasl_setprop failed: %d - %s",
- result, sasl_errdetail(context->conn));
- }
-
- return (VALUE) context;
-}
-
-//
-// Free a SASL client context.
-//
-static VALUE qsasl_free(int argc, VALUE *argv, VALUE obj)
-{
- context_t* context;
-
- if (argc == 1)
- context = (context_t*) argv[0];
- else
- rb_raise(rb_eRuntimeError, "Wrong Number of Arguments");
-
- if (context->conn)
- sasl_dispose(&context->conn);
- if (context->userName)
- free(context->userName);
- if (context->password)
- free(context->password);
- if (context->operUserName)
- free(context->operUserName);
- free(context);
-
- return Qnil;
-}
-
-//
-// Start the SASL exchange from the client's point of view.
-//
-static VALUE qsasl_client_start(int argc, VALUE *argv, VALUE obj)
-{
- context_t* context;
- char* mechList;
- char* mechToUse;
- int result;
- int propResult;
- const char* response;
- unsigned int len;
- sasl_interact_t* interact = 0;
- const char* chosen;
- const char* operName;
-
- if (argc == 2) {
- context = (context_t*) argv[0];
- mechList = StringValuePtr(argv[1]);
- } else
- rb_raise(rb_eRuntimeError, "Wrong Number of Arguments");
-
- if (strlen(context->mechanism) == 0)
- mechToUse = mechList;
- else
- mechToUse = context->mechanism;
-
- do {
- result = sasl_client_start(context->conn, mechToUse, &interact,
- &response, &len, &chosen);
- if (result == SASL_INTERACT) {
- qsasl_prompt(context, interact);
- }
- } while (result == SASL_INTERACT);
-
- if (result != SASL_OK && result != SASL_CONTINUE)
- rb_raise(rb_eRuntimeError, "sasl_client_start failed: %d - %s",
- result, sasl_errdetail(context->conn));
-
- if (result == SASL_OK) {
- propResult = sasl_getprop(context->conn, SASL_USERNAME, (const void**) &operName);
- if (propResult == SASL_OK) {
- context->operUserName = (char*) malloc(strlen(operName) + 1);
- strcpy(context->operUserName, operName);
- }
- }
-
- return rb_ary_new3(3, INT2NUM(result), rb_str_new(response, len), rb_str_new2(chosen));
-}
-
-//
-// Take a step in the SASL exchange (only needed for multi-challenge mechanisms).
-//
-static VALUE qsasl_client_step(int argc, VALUE *argv, VALUE obj)
-{
- context_t* context;
- VALUE challenge;
- int result;
- int propResult;
- const char* response;
- const char* operName;
- unsigned int len;
- sasl_interact_t* interact = 0;
-
- if (argc == 2) {
- context = (context_t*) argv[0];
- challenge = argv[1];
- }
- else
- rb_raise(rb_eRuntimeError, "Wrong Number of Arguments");
-
- do {
- result = sasl_client_step(context->conn,
- RSTRING(challenge)->ptr, RSTRING(challenge)->len,
- &interact, &response, &len);
- if (result == SASL_INTERACT) {
- qsasl_prompt(context, interact);
- }
- } while (result == SASL_INTERACT);
-
- if (result != SASL_OK && result != SASL_CONTINUE)
- return QSASL_FAILED;
-
- if (result == SASL_OK) {
- propResult = sasl_getprop(context->conn, SASL_USERNAME, (const void**) &operName);
- if (propResult == SASL_OK) {
- context->operUserName = (char*) malloc(strlen(operName) + 1);
- strcpy(context->operUserName, operName);
- }
- }
-
- return rb_ary_new3(2, INT2NUM(result), rb_str_new(response, len));
-}
-
-static VALUE qsasl_user_id(int argc, VALUE *argv, VALUE obj)
-{
- context_t* context;
-
- if (argc == 1) {
- context = (context_t*) argv[0];
- } else {
- rb_raise(rb_eRuntimeError, "Wrong Number of Arguments");
- }
-
- if (context->operUserName)
- return rb_str_new2(context->operUserName);
-
- return Qnil;
-}
-
-//
-// Encode transport data for the security layer.
-//
-static VALUE qsasl_encode(int argc, VALUE *argv, VALUE obj)
-{
- context_t* context;
- VALUE clearText;
- const char* outBuffer;
- unsigned int outSize;
- int result;
-
- if (argc == 2) {
- context = (context_t*) argv[0];
- clearText = argv[1];
- }
- else
- rb_raise(rb_eRuntimeError, "Wrong Number of Arguments");
-
- result = sasl_encode(context->conn,
- RSTRING(clearText)->ptr, RSTRING(clearText)->len,
- &outBuffer, &outSize);
- if (result != SASL_OK)
- rb_raise(rb_eRuntimeError, "sasl_encode failed: %d - %s",
- result, sasl_errdetail(context->conn));
-
- return rb_str_new(outBuffer, outSize);
-}
-
-//
-// Decode transport data for the security layer.
-//
-static VALUE qsasl_decode(int argc, VALUE *argv, VALUE obj)
-{
- context_t* context;
- VALUE cipherText;
- const char* outBuffer;
- unsigned int outSize;
- int result;
-
- if (argc == 2) {
- context = (context_t*) argv[0];
- cipherText = argv[1];
- }
- else
- rb_raise(rb_eRuntimeError, "Wrong Number of Arguments");
-
- result = sasl_decode(context->conn,
- RSTRING(cipherText)->ptr, RSTRING(cipherText)->len,
- &outBuffer, &outSize);
- if (result != SASL_OK)
- rb_raise(rb_eRuntimeError, "sasl_decode failed: %d - %s",
- result, sasl_errdetail(context->conn));
-
- return rb_str_new(outBuffer, outSize);
-}
-
-//
-// Initialize the Sasl module.
-//
-void Init_sasl()
-{
- mSasl = rb_define_module("Sasl");
-
- rb_define_module_function(mSasl, "client_init", qsasl_client_init, -1);
- rb_define_module_function(mSasl, "client_new", qsasl_client_new, -1);
- rb_define_module_function(mSasl, "free", qsasl_free, -1);
- rb_define_module_function(mSasl, "client_start", qsasl_client_start, -1);
- rb_define_module_function(mSasl, "client_step", qsasl_client_step, -1);
- rb_define_module_function(mSasl, "user_id", qsasl_user_id, -1);
- rb_define_module_function(mSasl, "encode", qsasl_encode, -1);
- rb_define_module_function(mSasl, "decode", qsasl_decode, -1);
-}