Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --- /home/para/dev/APE/crash/APE_Server/modules/libape-spidermonkey.c 2010-11-29 00:17:35.000000000 +0100
- +++ libape-spidermonkey.c 2011-02-22 10:14:59.000000000 +0100
- @@ -27,6 +27,7 @@
- #include <mysac.h>
- #endif
- #include <jsapi.h>
- +#include <libssh2.h>
- #include <stdio.h>
- #include <glob.h>
- #include "plugins.h"
- @@ -162,6 +163,34 @@
- static struct _ape_mysql_queue *apemysql_push_queue(struct _ape_mysql_data *myhandle, char *query, unsigned int query_len, jsval callback);
- static void apemysql_shift_queue(struct _ape_mysql_data *myhandle);
- #endif
- +
- +typedef enum {
- + SSH_STARTUP,
- + SSH_AUTH,
- + SSH_REQ_CHANNEL,
- + SSH_REQ_PTY,
- + SSH_REQ_SHELL,
- + SSH_CONNECTED,
- + SSH_ERR
- +} ape_ssh_state;
- +
- +struct _ape_ssh_ctx
- +{
- + JSContext *cx;
- + JSObject *jsssh;
- +
- + struct {
- + char *login;
- + char *password;
- + } cred;
- +
- + LIBSSH2_SESSION *session;
- + LIBSSH2_CHANNEL *channel;
- +
- + ape_ssh_state state;
- + void *data;
- +
- +};
- //static JSBool sockserver_addproperty(JSContext *cx, JSObject *obj, jsval idval, jsval *vp);
- static ace_plugin_infos infos_module = {
- @@ -267,6 +296,13 @@
- };
- #endif
- +static JSClass ssh_class = {
- + "SSH", JSCLASS_HAS_PRIVATE,
- + JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
- + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, apemysql_finalize,
- + JSCLASS_NO_OPTIONAL_MEMBERS
- +};
- +
- static JSClass cmdresponse_class = {
- "cmdresponse", JSCLASS_HAS_PRIVATE,
- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
- @@ -274,6 +310,40 @@
- JSCLASS_NO_OPTIONAL_MEMBERS
- };
- +APE_JS_NATIVE(apessh_sm_send)
- +//{
- + struct _ape_ssh_ctx *sshctx = JS_GetPrivate(cx, obj);
- + JSString *string;
- +
- + if (sshctx == NULL) {
- + return JS_TRUE;
- + }
- +
- + if (!JS_ConvertArguments(cx, argc, argv, "S", &string)) {
- + return JS_TRUE;
- + }
- +
- + libssh2_channel_write(sshctx->channel, JS_GetStringBytes(string), JS_GetStringLength(string));
- +
- + return JS_TRUE;
- +}
- +
- +APE_JS_NATIVE(apessh_sm_close)
- +//{
- + struct _ape_ssh_ctx *sshctx = JS_GetPrivate(cx, obj);
- + ape_socket *client;
- +
- + if (sshctx == NULL || sshctx->data == NULL) {
- + return JS_TRUE;
- + }
- +
- + client = (ape_socket *)sshctx->data;
- +
- + shutdown(client->fd, 2);
- +
- + return JS_TRUE;
- +}
- +
- APE_JS_NATIVE(apesocket_write)
- //{
- @@ -1127,6 +1197,13 @@
- JS_FS_END
- };
- +static JSFunctionSpec apessh_funcs[] = {
- + JS_FS("send", apessh_sm_send, 1, 0, 0),
- + JS_FS("close", apessh_sm_close, 0, 0, 0),
- + JS_FS_END
- +};
- +
- +
- static JSObject *sm_ape_socket_to_jsobj(JSContext *cx, ape_socket *client)
- {
- /*if (client->data != NULL) {
- @@ -1258,6 +1335,168 @@
- }
- }
- +/* Async State machine pour libssh2 */
- +static void ape_ssh_io(ape_socket *client, int way, acetables *g_ape)
- +{
- + int ret = 0, err = 0;
- + struct _ape_ssh_ctx *sshctx = client->attach;
- + const char *login, *pass;
- +
- + for (;;) {
- + switch(sshctx->state) {
- + case SSH_STARTUP:
- + if ((ret = libssh2_session_startup(sshctx->session, client->fd)) == 0) {
- + sshctx->state = SSH_AUTH;
- + } else if (ret != LIBSSH2_ERROR_EAGAIN) {
- + err = 1;
- + sshctx->state = SSH_ERR;
- + }
- + break;
- + case SSH_AUTH:
- + /* hmm, bug in the libssh2 macro?, useless ptr : */
- + login = sshctx->cred.login;
- + pass = sshctx->cred.password;
- +
- + if ((ret = libssh2_userauth_password(sshctx->session, login, pass)) == 0) {
- + sshctx->state = SSH_REQ_CHANNEL;
- + } else if (ret != LIBSSH2_ERROR_EAGAIN) {
- + err = 2;
- + sshctx->state = SSH_ERR;
- + }
- + break;
- + case SSH_REQ_CHANNEL:
- + if ((sshctx->channel = libssh2_channel_open_session(sshctx->session)) == NULL) {
- + ret = libssh2_session_last_errno(sshctx->session);
- + } else {
- + sshctx->state = SSH_REQ_PTY;
- + break;
- + }
- + if (sshctx->channel == NULL && ret != LIBSSH2_ERROR_EAGAIN) {
- + err = 3;
- + sshctx->state = SSH_ERR;
- + }
- + break;
- + case SSH_REQ_PTY:
- + if ((ret = libssh2_channel_request_pty(sshctx->channel, "vt100")) == 0) {
- + sshctx->state = SSH_REQ_SHELL;
- +
- + } else if (ret != LIBSSH2_ERROR_EAGAIN) {
- + err = 4;
- + sshctx->state = SSH_ERR;
- + }
- + break;
- + case SSH_REQ_SHELL:
- + if ((ret = libssh2_channel_shell(sshctx->channel)) == 0) {
- + jsval rval;
- + sshctx->state = SSH_CONNECTED;
- +
- + JS_CallFunctionName(sshctx->cx, sshctx->jsssh, "onShell", 0, NULL, &rval);
- + } else if (ret != LIBSSH2_ERROR_EAGAIN) {
- + err = 5;
- + sshctx->state = SSH_ERR;
- + }
- + break;
- + case SSH_CONNECTED:
- + {
- + char *buf = xmalloc(sizeof(char) * 2048);
- + int len = 0, r = 0;
- +
- + while ((r = libssh2_channel_read(sshctx->channel, buf + len, 2048)) > 0) {
- + len += r;
- + buf = realloc(buf, len + 2048);
- +
- + }
- + if (len > 0) {
- + jsval params[1], rval;
- + params[0] = STRING_TO_JSVAL(JS_NewStringCopyN(sshctx->cx, buf, len));
- +
- + JS_CallFunctionName(sshctx->cx, sshctx->jsssh, "onRead", 1, params, &rval);
- +
- + }
- + free(buf);
- + if (r == -1) {
- + err = 6;
- + sshctx->state = SSH_ERR;
- + break;
- + }
- +
- + }
- + //printf("[APE SSH] Connected !\n");
- + return;
- + break;
- + case SSH_ERR:
- + {
- + jsval params[1], rval;
- + params[0] = INT_TO_JSVAL(err);
- +
- + JS_CallFunctionName(sshctx->cx, sshctx->jsssh, "onError", 1, params, &rval);
- +
- + if (err > 1) {
- + libssh2_session_disconnect(sshctx->session, "Shutdown");
- + }
- + if (err > 3) {
- + libssh2_channel_free(sshctx->channel);
- + }
- +
- + shutdown(client->fd, 2);
- + close_socket(client->fd, g_ape);
- +
- + libssh2_session_free(sshctx->session);
- +
- + free(sshctx->cred.login);
- + free(sshctx->cred.password);
- +
- + JS_SetPrivate(sshctx->cx, sshctx->jsssh, NULL);
- + JS_RemoveRoot(sshctx->cx, &sshctx->jsssh);
- + client->attach = NULL;
- +
- + free(sshctx);
- +
- + }
- + return;
- +
- + }
- + if (ret == LIBSSH2_ERROR_EAGAIN) {
- + break;
- + }
- + }
- +}
- +
- +static void ape_ssh_io_read(ape_socket *client, ape_buffer *buf, size_t offset, acetables *g_ape)
- +{
- + struct _ape_ssh_ctx *sshctx = client->attach;
- +
- + if (sshctx != NULL && libssh2_session_block_directions(sshctx->session) & LIBSSH2_SESSION_BLOCK_INBOUND) {
- + ape_ssh_io(client, LIBSSH2_SESSION_BLOCK_INBOUND, g_ape);
- + }
- +
- +}
- +
- +static void ape_ssh_io_write(ape_socket *client, acetables *g_ape)
- +{
- + struct _ape_ssh_ctx *sshctx = client->attach;
- +
- + if (sshctx != NULL && libssh2_session_block_directions(sshctx->session) & LIBSSH2_SESSION_BLOCK_OUTBOUND) {
- + ape_ssh_io(client, LIBSSH2_SESSION_BLOCK_OUTBOUND, g_ape);
- + }
- +}
- +
- +
- +static void sm_ssh_onconnect(ape_socket *client, acetables *g_ape)
- +{
- + struct _ape_ssh_ctx *sshctx = client->attach;
- +
- + sshctx->data = client;
- +
- + client->stream_type = STREAM_DELEGATE;
- + client->callbacks.on_read = ape_ssh_io_read;
- + client->callbacks.on_write = ape_ssh_io_write;
- +
- + ape_ssh_io(client, 0, g_ape);
- +
- + /* turn to delegate */
- +}
- +
- static void sm_sock_onconnect(ape_socket *client, acetables *g_ape)
- {
- jsval rval;
- @@ -2503,6 +2742,73 @@
- return nqueue;
- }
- +/*
- +struct _ape_ssh_ctx
- +{
- + JSContext *ctx;
- + JSObject *jsssh;
- +
- + struct {
- + const char *login;
- + const char *password;
- + } cred;
- +
- + LIBSSH2_SESSION *session;
- +
- + int state;
- + void *data;
- +
- +};
- +*/
- +
- +
- +APE_JS_NATIVE(ape_sm_ssh_constructor)
- +//{
- + LIBSSH2_SESSION *session;
- + char *ip, *login, *pass;
- +
- + ape_socket *pattern;
- + struct _ape_ssh_ctx *sshctx;
- +
- + /* var ssh = new Ape.SSH('ape-project.org', 'root', 'lefu-'); */
- + if (!JS_ConvertArguments(cx, argc, argv, "sss", &ip, &login, &pass)) {
- + return JS_TRUE;
- + }
- +
- + session = libssh2_session_init();
- +
- + if (session == 0) {
- + return JS_TRUE;
- + }
- +
- + libssh2_session_set_blocking(session, 0);
- +
- + sshctx = xmalloc(sizeof(*sshctx));
- +
- + sshctx->cred.login = xstrdup(login);
- + sshctx->cred.password = xstrdup(pass);
- + sshctx->session = session;
- + sshctx->cx = cx;
- + sshctx->jsssh = obj;
- + sshctx->state = SSH_STARTUP;
- + sshctx->data = NULL;
- +
- + JS_AddRoot(cx, &sshctx->jsssh);
- +
- + pattern = xmalloc(sizeof(*pattern));
- +
- + pattern->callbacks.on_connect = sm_ssh_onconnect;
- + pattern->callbacks.on_disconnect = NULL;
- +
- + pattern->attach = sshctx;
- +
- + JS_SetPrivate(cx, obj, sshctx);
- +
- + ape_connect_name(ip, 22, pattern, g_ape);
- +
- + return JS_TRUE;
- +}
- +
- APE_JS_NATIVE(ape_sm_mysql_constructor)
- //{
- char *host, *login, *pass, *db;
- @@ -2678,6 +2984,7 @@
- #ifdef _USE_MYSQL
- JSObject *jsmysql;
- #endif
- + JSObject *jsssh;
- obj = JS_DefineObject(asc->cx, asc->global, "Ape", &ape_class, NULL, 0);
- b64 = JS_DefineObject(asc->cx, obj, "base64", &b64_class, NULL, 0);
- @@ -2707,10 +3014,13 @@
- #ifdef _USE_MYSQL
- jsmysql = JS_InitClass(asc->cx, obj, NULL, &mysql_class, ape_sm_mysql_constructor, 2, NULL, NULL, NULL, apemysql_funcs_static);
- #endif
- + jsssh = JS_InitClass(asc->cx, obj, NULL, &ssh_class, ape_sm_ssh_constructor, 3, NULL, NULL, NULL, NULL);
- JS_InitClass(asc->cx, obj, NULL, &raw_class, ape_sm_raw_constructor, 1, NULL, NULL, NULL, NULL); /* Not used */
- JS_DefineFunctions(asc->cx, sockclient, apesocket_client_funcs);
- JS_DefineFunctions(asc->cx, sockclient, apesocket_funcs);
- +
- + JS_DefineFunctions(asc->cx, jsssh, apessh_funcs);
- JS_DefineFunctions(asc->cx, sockserver, apesocket_client_funcs);
- JS_DefineFunctions(asc->cx, sockserver, apesocketserver_funcs);
- @@ -2886,7 +3196,7 @@
- glob_t globbuf;
- - rt = JS_NewRuntime(8L * 1024L * 1024L);
- + rt = JS_NewRuntime(128L * 1024L * 1024L);
- if (rt == NULL) {
- printf("[ERR] Not enougth memory\n");
- @@ -2912,6 +3222,10 @@
- glob(rpath, 0, NULL, &globbuf);
- + if (libssh2_init(0) != 0) {
- + printf("[SSH] Error: Failed to initialize libssh2\n");
- + }
- +
- for (i = 0; i < globbuf.gl_pathc; i++) {
- ape_sm_compiled *asc = xmalloc(sizeof(*asc));
Add Comment
Please, Sign In to add comment