lua/lstate.h
author Ryan C. Gordon <icculus@icculus.org>
Fri, 23 Jun 2017 17:28:03 -0400
changeset 58 1390348facc7
parent 0 d7ee4e2ed49d
permissions -rw-r--r--
Command line tool that decrypts an OPVault keychain and dumps it to stdout.

To compile: gcc -o opvault opvault.c cJSON.c -lcrypto

Usage: ./opvault </path/to/mykeychain.opvault> <password>

This is just a proof of concept; I'll be recycling this into proper OPVault
support in 1pass later and deleting this tool.

This uses OpenSSL's libcrypto for the math instead of all the homegrown
crypto this project is otherwise using. I'll probably migrate the rest in
this direction, too, since this wasn't as bad as I expected to use and
gets you all the package-manager mojo of automatic bug fixes and security
patches and shared code, etc.

cJSON parses JSON in C. That is from https://github.com/DaveGamble/cJSON

An example OPVault keychain from AgileBits is available here:

https://cache.agilebits.com/security-kb/
icculus@0
     1
/*
icculus@0
     2
** $Id: lstate.h,v 2.82.1.1 2013/04/12 18:48:47 roberto Exp $
icculus@0
     3
** Global State
icculus@0
     4
** See Copyright Notice in lua.h
icculus@0
     5
*/
icculus@0
     6
icculus@0
     7
#ifndef lstate_h
icculus@0
     8
#define lstate_h
icculus@0
     9
icculus@0
    10
#include "lua.h"
icculus@0
    11
icculus@0
    12
#include "lobject.h"
icculus@0
    13
#include "ltm.h"
icculus@0
    14
#include "lzio.h"
icculus@0
    15
icculus@0
    16
icculus@0
    17
/*
icculus@0
    18
icculus@0
    19
** Some notes about garbage-collected objects:  All objects in Lua must
icculus@0
    20
** be kept somehow accessible until being freed.
icculus@0
    21
**
icculus@0
    22
** Lua keeps most objects linked in list g->allgc. The link uses field
icculus@0
    23
** 'next' of the CommonHeader.
icculus@0
    24
**
icculus@0
    25
** Strings are kept in several lists headed by the array g->strt.hash.
icculus@0
    26
**
icculus@0
    27
** Open upvalues are not subject to independent garbage collection. They
icculus@0
    28
** are collected together with their respective threads. Lua keeps a
icculus@0
    29
** double-linked list with all open upvalues (g->uvhead) so that it can
icculus@0
    30
** mark objects referred by them. (They are always gray, so they must
icculus@0
    31
** be remarked in the atomic step. Usually their contents would be marked
icculus@0
    32
** when traversing the respective threads, but the thread may already be
icculus@0
    33
** dead, while the upvalue is still accessible through closures.)
icculus@0
    34
**
icculus@0
    35
** Objects with finalizers are kept in the list g->finobj.
icculus@0
    36
**
icculus@0
    37
** The list g->tobefnz links all objects being finalized.
icculus@0
    38
icculus@0
    39
*/
icculus@0
    40
icculus@0
    41
icculus@0
    42
struct lua_longjmp;  /* defined in ldo.c */
icculus@0
    43
icculus@0
    44
icculus@0
    45
icculus@0
    46
/* extra stack space to handle TM calls and some other extras */
icculus@0
    47
#define EXTRA_STACK   5
icculus@0
    48
icculus@0
    49
icculus@0
    50
#define BASIC_STACK_SIZE        (2*LUA_MINSTACK)
icculus@0
    51
icculus@0
    52
icculus@0
    53
/* kinds of Garbage Collection */
icculus@0
    54
#define KGC_NORMAL	0
icculus@0
    55
#define KGC_EMERGENCY	1	/* gc was forced by an allocation failure */
icculus@0
    56
#define KGC_GEN		2	/* generational collection */
icculus@0
    57
icculus@0
    58
icculus@0
    59
typedef struct stringtable {
icculus@0
    60
  GCObject **hash;
icculus@0
    61
  lu_int32 nuse;  /* number of elements */
icculus@0
    62
  int size;
icculus@0
    63
} stringtable;
icculus@0
    64
icculus@0
    65
icculus@0
    66
/*
icculus@0
    67
** information about a call
icculus@0
    68
*/
icculus@0
    69
typedef struct CallInfo {
icculus@0
    70
  StkId func;  /* function index in the stack */
icculus@0
    71
  StkId	top;  /* top for this function */
icculus@0
    72
  struct CallInfo *previous, *next;  /* dynamic call link */
icculus@0
    73
  short nresults;  /* expected number of results from this function */
icculus@0
    74
  lu_byte callstatus;
icculus@0
    75
  ptrdiff_t extra;
icculus@0
    76
  union {
icculus@0
    77
    struct {  /* only for Lua functions */
icculus@0
    78
      StkId base;  /* base for this function */
icculus@0
    79
      const Instruction *savedpc;
icculus@0
    80
    } l;
icculus@0
    81
    struct {  /* only for C functions */
icculus@0
    82
      int ctx;  /* context info. in case of yields */
icculus@0
    83
      lua_CFunction k;  /* continuation in case of yields */
icculus@0
    84
      ptrdiff_t old_errfunc;
icculus@0
    85
      lu_byte old_allowhook;
icculus@0
    86
      lu_byte status;
icculus@0
    87
    } c;
icculus@0
    88
  } u;
icculus@0
    89
} CallInfo;
icculus@0
    90
icculus@0
    91
icculus@0
    92
/*
icculus@0
    93
** Bits in CallInfo status
icculus@0
    94
*/
icculus@0
    95
#define CIST_LUA	(1<<0)	/* call is running a Lua function */
icculus@0
    96
#define CIST_HOOKED	(1<<1)	/* call is running a debug hook */
icculus@0
    97
#define CIST_REENTRY	(1<<2)	/* call is running on same invocation of
icculus@0
    98
                                   luaV_execute of previous call */
icculus@0
    99
#define CIST_YIELDED	(1<<3)	/* call reentered after suspension */
icculus@0
   100
#define CIST_YPCALL	(1<<4)	/* call is a yieldable protected call */
icculus@0
   101
#define CIST_STAT	(1<<5)	/* call has an error status (pcall) */
icculus@0
   102
#define CIST_TAIL	(1<<6)	/* call was tail called */
icculus@0
   103
#define CIST_HOOKYIELD	(1<<7)	/* last hook called yielded */
icculus@0
   104
icculus@0
   105
icculus@0
   106
#define isLua(ci)	((ci)->callstatus & CIST_LUA)
icculus@0
   107
icculus@0
   108
icculus@0
   109
/*
icculus@0
   110
** `global state', shared by all threads of this state
icculus@0
   111
*/
icculus@0
   112
typedef struct global_State {
icculus@0
   113
  lua_Alloc frealloc;  /* function to reallocate memory */
icculus@0
   114
  void *ud;         /* auxiliary data to `frealloc' */
icculus@0
   115
  lu_mem totalbytes;  /* number of bytes currently allocated - GCdebt */
icculus@0
   116
  l_mem GCdebt;  /* bytes allocated not yet compensated by the collector */
icculus@0
   117
  lu_mem GCmemtrav;  /* memory traversed by the GC */
icculus@0
   118
  lu_mem GCestimate;  /* an estimate of the non-garbage memory in use */
icculus@0
   119
  stringtable strt;  /* hash table for strings */
icculus@0
   120
  TValue l_registry;
icculus@0
   121
  unsigned int seed;  /* randomized seed for hashes */
icculus@0
   122
  lu_byte currentwhite;
icculus@0
   123
  lu_byte gcstate;  /* state of garbage collector */
icculus@0
   124
  lu_byte gckind;  /* kind of GC running */
icculus@0
   125
  lu_byte gcrunning;  /* true if GC is running */
icculus@0
   126
  int sweepstrgc;  /* position of sweep in `strt' */
icculus@0
   127
  GCObject *allgc;  /* list of all collectable objects */
icculus@0
   128
  GCObject *finobj;  /* list of collectable objects with finalizers */
icculus@0
   129
  GCObject **sweepgc;  /* current position of sweep in list 'allgc' */
icculus@0
   130
  GCObject **sweepfin;  /* current position of sweep in list 'finobj' */
icculus@0
   131
  GCObject *gray;  /* list of gray objects */
icculus@0
   132
  GCObject *grayagain;  /* list of objects to be traversed atomically */
icculus@0
   133
  GCObject *weak;  /* list of tables with weak values */
icculus@0
   134
  GCObject *ephemeron;  /* list of ephemeron tables (weak keys) */
icculus@0
   135
  GCObject *allweak;  /* list of all-weak tables */
icculus@0
   136
  GCObject *tobefnz;  /* list of userdata to be GC */
icculus@0
   137
  UpVal uvhead;  /* head of double-linked list of all open upvalues */
icculus@0
   138
  Mbuffer buff;  /* temporary buffer for string concatenation */
icculus@0
   139
  int gcpause;  /* size of pause between successive GCs */
icculus@0
   140
  int gcmajorinc;  /* pause between major collections (only in gen. mode) */
icculus@0
   141
  int gcstepmul;  /* GC `granularity' */
icculus@0
   142
  lua_CFunction panic;  /* to be called in unprotected errors */
icculus@0
   143
  struct lua_State *mainthread;
icculus@0
   144
  const lua_Number *version;  /* pointer to version number */
icculus@0
   145
  TString *memerrmsg;  /* memory-error message */
icculus@0
   146
  TString *tmname[TM_N];  /* array with tag-method names */
icculus@0
   147
  struct Table *mt[LUA_NUMTAGS];  /* metatables for basic types */
icculus@0
   148
} global_State;
icculus@0
   149
icculus@0
   150
icculus@0
   151
/*
icculus@0
   152
** `per thread' state
icculus@0
   153
*/
icculus@0
   154
struct lua_State {
icculus@0
   155
  CommonHeader;
icculus@0
   156
  lu_byte status;
icculus@0
   157
  StkId top;  /* first free slot in the stack */
icculus@0
   158
  global_State *l_G;
icculus@0
   159
  CallInfo *ci;  /* call info for current function */
icculus@0
   160
  const Instruction *oldpc;  /* last pc traced */
icculus@0
   161
  StkId stack_last;  /* last free slot in the stack */
icculus@0
   162
  StkId stack;  /* stack base */
icculus@0
   163
  int stacksize;
icculus@0
   164
  unsigned short nny;  /* number of non-yieldable calls in stack */
icculus@0
   165
  unsigned short nCcalls;  /* number of nested C calls */
icculus@0
   166
  lu_byte hookmask;
icculus@0
   167
  lu_byte allowhook;
icculus@0
   168
  int basehookcount;
icculus@0
   169
  int hookcount;
icculus@0
   170
  lua_Hook hook;
icculus@0
   171
  GCObject *openupval;  /* list of open upvalues in this stack */
icculus@0
   172
  GCObject *gclist;
icculus@0
   173
  struct lua_longjmp *errorJmp;  /* current error recover point */
icculus@0
   174
  ptrdiff_t errfunc;  /* current error handling function (stack index) */
icculus@0
   175
  CallInfo base_ci;  /* CallInfo for first level (C calling Lua) */
icculus@0
   176
};
icculus@0
   177
icculus@0
   178
icculus@0
   179
#define G(L)	(L->l_G)
icculus@0
   180
icculus@0
   181
icculus@0
   182
/*
icculus@0
   183
** Union of all collectable objects
icculus@0
   184
*/
icculus@0
   185
union GCObject {
icculus@0
   186
  GCheader gch;  /* common header */
icculus@0
   187
  union TString ts;
icculus@0
   188
  union Udata u;
icculus@0
   189
  union Closure cl;
icculus@0
   190
  struct Table h;
icculus@0
   191
  struct Proto p;
icculus@0
   192
  struct UpVal uv;
icculus@0
   193
  struct lua_State th;  /* thread */
icculus@0
   194
};
icculus@0
   195
icculus@0
   196
icculus@0
   197
#define gch(o)		(&(o)->gch)
icculus@0
   198
icculus@0
   199
/* macros to convert a GCObject into a specific value */
icculus@0
   200
#define rawgco2ts(o)  \
icculus@0
   201
	check_exp(novariant((o)->gch.tt) == LUA_TSTRING, &((o)->ts))
icculus@0
   202
#define gco2ts(o)	(&rawgco2ts(o)->tsv)
icculus@0
   203
#define rawgco2u(o)	check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
icculus@0
   204
#define gco2u(o)	(&rawgco2u(o)->uv)
icculus@0
   205
#define gco2lcl(o)	check_exp((o)->gch.tt == LUA_TLCL, &((o)->cl.l))
icculus@0
   206
#define gco2ccl(o)	check_exp((o)->gch.tt == LUA_TCCL, &((o)->cl.c))
icculus@0
   207
#define gco2cl(o)  \
icculus@0
   208
	check_exp(novariant((o)->gch.tt) == LUA_TFUNCTION, &((o)->cl))
icculus@0
   209
#define gco2t(o)	check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
icculus@0
   210
#define gco2p(o)	check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
icculus@0
   211
#define gco2uv(o)	check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
icculus@0
   212
#define gco2th(o)	check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th))
icculus@0
   213
icculus@0
   214
/* macro to convert any Lua object into a GCObject */
icculus@0
   215
#define obj2gco(v)	(cast(GCObject *, (v)))
icculus@0
   216
icculus@0
   217
icculus@0
   218
/* actual number of total bytes allocated */
icculus@0
   219
#define gettotalbytes(g)	((g)->totalbytes + (g)->GCdebt)
icculus@0
   220
icculus@0
   221
LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt);
icculus@0
   222
LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
icculus@0
   223
LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
icculus@0
   224
LUAI_FUNC void luaE_freeCI (lua_State *L);
icculus@0
   225
icculus@0
   226
icculus@0
   227
#endif
icculus@0
   228